HDU 4602 Partition

f[i]表示和为i的方案数。已知f[i]=2i-1

dp[i]表示和为i,k有多少个。那么dp[i]=dp[1]+dp[2]+...+dp[i-1]+f[i-k]。

考虑与f有关的项:

f[n-k]是答案的一部分,即2n-k-1是答案的一部分。

把与dp有关的项:

令s[i-1]=dp[1]+dp[2]+...+dp[i-1],那么s[n-1]是答案的一部分。

s[i]=s[i-1]+dp[i],又dp[i]=s[i-1]+f[i-k]。推出s[i]=2*s[i-1]+f[i-k],dp[k]=s[k]=1。

可以推出s[n-1]=2n-k-1+(n-k-1)*2n-k-2

 1 #include<iostream>
 2 typedef long long LL;
 3 LL MOD = 1000000007LL;
 4 using namespace std;
 5 LL powmod(LL a, LL b) {
 6     LL ans;
 7     a %= MOD;
 8     for (ans = 1; b; b >>= 1) {
 9         if (b & 1) {
10             ans *= a;
11             ans %= MOD;
12         }
13         a *= a;
14         a %= MOD;
15     }
16     return ans;
17 }
18 int main() {
19     int T;
20     LL n, k;
21     LL ans;
22     cin >> T;
23     while (T--) {
24         cin >> n >> k;
25         if (k > n) {
26             ans = 0;
27         } else if (k == n) {
28             ans = 1;
29         } else if (n - k == 1) {
30             ans = 2;
31         } else if (n - k == 2) {
32             ans = 5;
33         } else {
34             ans = powmod(2, n - k - 1)
35                     + (n - k - 1) * powmod(2, n - k - 2) % MOD;
36             ans += powmod(2, n - k - 1);
37             ans = (ans % MOD + MOD) % MOD;
38         }
39         cout << ans << endl;
40     }
41     return 0;
42 }
View Code

相关文章: