Partition
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1293 Accepted Submission(s): 777
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 ≤ 10
5) 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
这道题一看,以为是简单的数字拆分,然而常规方法是肯定超时的,因为他的范围能到100000,用母函数肯定超时,结果在网上找到了拆分数字的通项公式..
就是f[n]=∑(-1)^k*f[n-k*k*3/2+k/2]+∑(-1)^k*f[n-k*k*3/2-k/2]
前后两项分别都是只有是正的时候才加上,一直加到前后两项都是负的时候才跳出.
#include<iostream>
using namespace std;
int main(){
int i,j;
int a[111111];
a[0]=1;
int flag=1;
for(i=1;i<=100000;i++)
{
a[i]=0;
for(j=1;;j++)
{
int t=i-j*(j*3-1)/2;
int tt=i-j*(j*3+1)/2;
if(1&j)
flag=1;
else flag=-1;
if(t<0&&tt<0)
{
break;
}
if(t>=0)
a[i]=(a[i]+flag*a[t])%1000000007;
if(tt>=0)
a[i]=(a[i]+flag*a[tt])%1000000007;
}
a[i]=(a[i]+1000000007)%1000000007;
}
int n;cin>>n;
while(n--)
{
int n1;
cin>>n1;
cout<<a[n1]<<endl;
}
return 0;
}