Sum of Distinct Numbers |
Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:32768KB |
Total submit users: 3, Accepted users: 3 |
Problem 13098 : No special judgement |
Problem description |
A positive integer N can be written in the form of sum of distinct positive integers in several ways. For example, |
Input |
You are given the number of test cases (1 <= T <= 20) in the first line. Then, in the following T lines, each line contains the number N (1 <= N <= 2,000). |
Output |
Print out, for each number N, the number of possible ways of writing that number in the form of sum of distinct numbers as described above. In order to limit the range of answers, the answer must be the result value modulo 100999. |
Sample Input |
4 5 6 10 200 |
Sample Output |
3 4 10 50568 |
题意就是给出一个数N,求组成N的不同数有多少种方式。如样例5={1+4},{2+3},{5}就有三种。
解题思路:N分别减去j=[1,(n-1)/2],剩下的数m,看m除掉前j个组成的数还有多少种组成方式。直接从1递推到2000即可。由于时间复杂度=2000*1000*1000左右,可能会超时,所以在计算m的时候,可以用辅助数组g[i][j](表示当前i,前j项的和)来计算。这里有一点点小问题,仔细考虑清楚下。
比如N=10.N可以减去1,2,3,4.分别余下9,8,7,6.分别看当m=9的时候组成9的数不包含1有多少种,当m=8的时候组成数不包含1,2的有多少种,。。。然后这些种类的和就是N=10的结果。在处理m这些数据的时候,顺便把他们的结果也保存下来,让下一次计算准备调用。嗯,就这样了。还T了,Wr了这么多发,淡淡的忧伤。。。肯定是没睡好,嗯,继续补觉。。。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <list>
#include <vector>
#include <ctime>
#define LL __int64
#define eps 1e-8
#define M 100999
using namespace std;
int f[2010][2010];
int g[2010][2010];
int main()
{
int i,n,j,T;
// freopen("out1.txt","w",stdout);
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));
f[1][0]=1;
for (i=2;i<=2010;i++)
{
f[i][0]=1;
for (j=1;j<=(i-1)/2;j++)
{
LL s=f[i-j][0];
g[i][0]=0;
int jj=j;
while (g[i-j][jj]==0 && g[i-j][jj+1]==0 && jj>0) jj--;
s=(s+M-g[i-j][jj])%M;
f[i][j]=s;
g[i][j]=(g[i][j-1]%M+s%M)%M;
f[i][0]=(f[i][0]+s)%M;
}
}
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
//cout<<n<<endl;
printf("%d\n",f[n][0]);
}
return 0;
}