hdu 4651 Partition(整数拆分+五边形数)
Partition
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 462 Accepted Submission(s): 262
Problem Description
How many ways can the numbers 1 to 15 be added together to make 15? The technical term for what you are asking is the "number of partition" which is often called P(n). A partition of n is a collection of positive integers (not necessarily distinct) whose sum equals n.
Now, I will give you a number n, and please tell me P(n) mod 1000000007.
Now, I will give you a number n, and please tell me P(n) mod 1000000007.
Input
The first line contains a number T(1 ≤ T ≤ 100), which is the number of the case number. The next T lines, each line contains a number n(1 ≤ n ≤ 105) you need to consider.
Output
For each n, output P(n) in a single line.
Sample Input
4
5
11
15
19
Sample Output
7
56
176
490
Source
Recommend
zhuyuanchen520
的生成函数是
- (1)
- 再
利用五边形数定理可得到以下的展开式:
- (2)
- 将(2)式带入(1)式,并乘到(1)式的左边,进行展开,合并同类项,根据非常数项的系数为0!!
- 即将生成函数配合五边形数定理,可以得到以下的递归关系式
1 #include<stdio.h> 2 typedef long long ll; 3 const int mo=1000000007; 4 ll p[100010]; 5 void pre()//打表,欧拉函数的倒数是分割函数的母函数!!! 6 { 7 p[0]=1; 8 for(ll i=1;i<=100000;i++) 9 { 10 ll t=1,ans=0,kk=1; 11 while(1) 12 { 13 ll tmp1,tmp2; 14 tmp1=(3*kk*kk-kk)/2; 15 tmp2=(3*kk*kk+kk)/2; 16 if(tmp1>i)break; 17 ans=(ans+t*p[i-tmp1]+mo)%mo; 18 if(tmp2>i)break; 19 ans=(ans+t*p[i-tmp2]+mo)%mo; 20 t=-t; 21 kk++; 22 } 23 p[i]=ans; 24 } 25 } 26 int main() 27 { 28 pre(); 29 int T,n; 30 scanf("%d",&T); 31 while(T--) 32 { 33 scanf("%d",&n); 34 printf("%lld\n",p[n]); 35 } 36 }