整数划分 划分成单峰的回文数列
dp[i][j] 表示 把i划分,其中划分的数不能大于j
1 i=1或j=1
dp[i][j]= dp[i][j-1]+1 j=i
dp(i,j-1)+dp(i-j,min(i-j,j)) i>j>1
1 #include <iostream> 2 #include <cstdio> 3 #include <string.h> 4 using namespace std; 5 int main(){ 6 int a; 7 long long dp[305][305],sum[305]; 8 memset(dp,0,sizeof(dp)); 9 for(int i=0;i<305;i++){ 10 dp[0][i]=1; //令dp[0][i]=1则 i=j时 dp[i-j][min(j,i-j)]=1; 11 } 12 for(int i=1;i<305;i++){ 13 for(int j=1;j<=i;j++){ 14 dp[i][j]=dp[i-j][min(j,i-j)]+dp[i][j-1]; 15 } 16 } 17 for(int i=1;i<305;i++){ 18 if(!(i&1))sum[i]=dp[i/2][i/2]; 19 else sum[i]=0; 20 for(int j=i;j>0;j-=2){ 21 sum[i]+=dp[(i-j)/2][min((i-j)/2,j)]; 22 } 23 } 24 while(scanf("%d",&a),a){ 25 printf("%d %lld ",a,sum[a]); 26 } 27 }