本题大意是,对于某一个数,有多少回文的组合方式。第一反应就是使用DP,状态的定义:d(i,k)表示数i中,组合数大于k的个数。因此d(i,k)=∑d(i-2j,j),j<n/2;需要注意的是要对j>=n/2的情况,使d(i,j)=1。此题特别需要注意的是要使用int64的数据类型,对应的输出要使用"%lld",否则会溢出。
#include <stdio.h>
#include<string.h>
typedef long long INT64;
INT64 nums[500][500];
INT64 getResult(int n,int d);
int main()
{
int n,i;
INT64 result;
memset(nums,0,sizeof(nums));
//freopen("test.txt","r",stdin);
while(scanf("%d",&n))
{
if(n==0)
break;
result=getResult(n,1);
printf("%d %lld\n",n,result);
}
return 0;
}
INT64 getResult(int n,int d)
{
int i,j;
INT64 sum;
if(nums[n][d]>0)
return nums[n][d];
if(n<d)
return 0;
for(i=n;i>n/2;i--)
nums[n][i]=1;
sum=1;
for(i=n/2;i>=d;i--)
{
if(i*2==n)
sum+=1;
else
{
sum+=getResult(n-2*i,i);
}
nums[n][i]=sum;
}
return nums[n][d];
}
对于测试数据:
1
2
3
4
5
6
7
8
10
23
24
131
213
92
231
0
结果:
1 1
2 2
3 2
4 4
5 3
6 7
7 5
8 11
10 17
23 104
24 199
131 5010688
213 1055852590
92 331143
231 2973772212