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\n",solve()); 63 } 64 return 0; 65 }