Partition
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 916 Accepted Submission(s): 527
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
题意:整数拆分,把n分成若干个数相加的种数。
思路:易知其母函数为:G(x)=(1+x+x^2+...)*(1+x^2+x^4+...)*(1+x^n+...),即:
由五边形定理可以知道G(x)=sigma(P(k)x^k),其中P(n)=P(n-1)+P(n-2)-P(n-5)-P(n-7)+...
http://zh.wikipedia.org/wiki/%E4%BA%94%E9%82%8A%E5%BD%A2%E6%95%B8%E5%AE%9A%E7%90%86
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <string.h>
#define LL long long
#define scan(a) scanf("%d",&a)
#define REP(i,a,b) for(int i=a;i<b;++i)
#define mset(a,b) memset(a,b,sizeof a)
#define mod 1000000007
const int maxn=1e5+10;
using namespace std;
LL ans[maxn];
inline LL pj(LL j)
{
LL ret = (3*j*j+j)/2;
return ret;
}
void init()
{
mset(ans,0);
ans[0]=1;
REP(i,1,maxn)
{
for(int j=1;pj(-j)<=i;++j)
{
int r=(j%2)?1:-1;
int a=pj(-j);
int b=pj(j);
if(a<=i)
{
ans[i]+=ans[i-a]*r;
ans[i]=(ans[i]%mod+mod)%mod;
}
if(b<=i)
{
ans[i]+=ans[i-b]*r;
ans[i]=(ans[i]%mod+mod)%mod;
}
}
}
}
int main()
{
int t;
int n;
init();
cin>>t;
while(t--)
{
scan(n);
printf("%I64d\n",ans[n]);
}
}