小A与小姐姐给气球涂色[dp + 快速幂]

小A与小姐姐给气球涂色
时间限制:1 sec 内存限制:128 MB
提交:2 正确:1

题目描述
小A与小姐姐闲的无聊,它们路过一家商店,看见里面有很多无色的气球,于是他们突然有一个想法,自己买气球,把气球涂成不同的颜色,然后送给商店旁边小学里小朋友。他们买了n只气球,m中涂料,他们把气球排成一排,他们送给小朋友的气球的顺序也是排列的顺序。初始时,气球的都是无色的,现在他们想用m种涂料给气球涂色,他们不想送给相邻小朋友的气球的颜色相同,即排列的气球相邻的颜色相同则视为送给相邻的小朋友的气球颜色相同,如果相邻的气球的颜色相同,拥有这2个气球的小朋友会不开心。小姐姐希望小A求出使小朋友开心的涂色方案有多少种(即相邻的两个气球颜色不相同的涂色方案有多少种)。

输出答案对1000000007取余。

输入
输入两个整数n(1 <= n <= 1012),m(1 <= m <= 108)。

输出
输出一行表示答案。

样例输入

2 2

样例输出

2

思路:假设有n个气球,m种颜色,那么也只是在 n-1个气球,m种颜色上多了以个其球罢了,然后最后面的气球上的色不能和它前面一个相同,所以它就有C(1, m -1);种上色情况,因为是相互独立,所以就的递推公式

dp[i][j] = dp[i - 1][j] * dp[1][m - 1];

所以可以解出来

题解:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 typedef long long ll;
 5 const int mod = 1e9 + 7;
 6 int f2;
 7 long long ksm(ll m, ll n)
 8 {
 9     long long res = 1;
10     while (n)
11     {
12         if (n&1) res = res * m % mod;
13         m = m * m % mod;
14         n >>= 1; 
15     
16     } 
17     return res;
18 }
19 
20 int main()
21 {
22     ll n, m;
23     while(cin >> n >> m){
24     
25     n %= mod;
26     m %= mod;
27     if (m == 1)
28     {
29         if (n == 1)
30             cout << 1 << endl;
31         else cout << 0 << endl;
32     }
33     else
34     {
35         cout << m * ksm(m - 1, n - 1) % mod << endl;
36     }
37 }
38     return 0;
39 }
追求吾之所爱
原文地址:https://www.cnblogs.com/rstz/p/12393214.html