题意:数拆分成回文数的方法数目。记res[n][k]为拆分数和为n,拆分的数中最小为k的拆分方法数目,则res[n][k]=sum(res[n-2k][k],res[n-2k-2][k+1],....)。有两点细节要注意:一是每个数可以只拆分成一个数,即该数本身;二是对于偶数n=2t,还可以拆成(t,t)的形式,需要额外+1。
#include <iostream>
using namespace std;
int n=0;
int num[1000];
int big=-1;
long long res[1000][1000]={0}; //注意用64位,否则会溢出
int MAX(int a,int b)
{
return a>b?a:b;
}
int main()
{
freopen("a.txt","r",stdin);
int t;
cin>>t;
while(t>0)
{
num[n]=t;
n++;
big=MAX(big,t);
cin>>t;
}
for(int i=1;i<=big;i++)
for(int k=big;k>=1;k--)
{
if(2*k>i) res[i][k]=1;
if(2*k==i) res[i][k]=2;
if(res[i][k]>0) continue;
for(int s=0;3*s<=i-3*k;s++)
{
res[i][k]+=res[i-2*k-2*s][k+s];
}
res[i][k]++; //注意的细节1
if(i%2==0) res[i][k]++; //注意的细节2
}
for(int i=0;i<n;i++)
cout<<num[i]<<' '<<res[num[i]][1]<<endl;
return 0;
}