hdu 4658 Integer Partition

五角数定理!!可以参考这个http://www.cnblogs.com/xin-hua/p/3242428.html

 代码如下:

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<iomanip>
 5 #include<cmath>
 6 #include<string>
 7 #include<vector>
 8 #define ll __int64
 9 #define pi acos(-1.0)
10 #define MAX 100001
11 using namespace std;
12 const int mod=1000000007;
13 int an[MAX],n,t,k;
14 void init(){
15     int i,j;
16     an[0]=an[1]=1;
17     an[2]=2;an[3]=3;an[4]=5;
18     an[5]=7;
19     for(i=6;i<MAX;i++){
20         an[i]=0;
21         for(j=1;;j++){
22             int g=j*(3*j-1)/2;
23             if(i-g<0) break;
24             if(j&1) an[i]+=an[i-g];
25             else an[i]-=an[i-g];
26             an[i]=an[i]%mod;
27             while(an[i]<0) an[i]+=mod;
28             g=j*(3*j+1)/2;
29             if(i-g<0) break;
30             if(j&1) an[i]+=an[i-g];
31             else an[i]-=an[i-g];
32             an[i]=an[i]%mod;
33             while(an[i]<0) an[i]+=mod;
34         }
35         an[i]%=mod;
36     }
37 }
38 int solve()
39 {
40     int ans=an[n];
41     for(int j=1;;j++){
42         int g=k*j*(3*j-1)/2;
43         if(n-g<0) break;
44         if(j&1) ans-=an[n-g];
45         else ans+=an[n-g];
46         ans=ans%mod;
47         while(ans<0) ans+=mod;
48         g=k*j*(3*j+1)/2;
49         if(n-g<0) break;
50         if(j&1) ans-=an[n-g];
51         else ans+=an[n-g];
52         ans=ans%mod;
53         while(ans<0) ans+=mod;
54     }
55     return ans%mod;
56 }
57 int main(){
58     init();
59     scanf("%d",&t);
60     while(t--){
61         scanf("%d%d",&n,&k);
62         printf("%d
",solve());
63     }
64     return 0;
65 }
View Code
原文地址:https://www.cnblogs.com/xin-hua/p/3248254.html