题意:若干组数据,分别问 N划分成K个正整数之和的划分数目、N划分成若干个不同正整数之和的划分数目、N划分成若干个奇正整数之和的划分数目。
解法:请见我之前的一篇博文内的Article 2——【noi 2.6_8787】数的划分(DP){附【转】整数划分的解题方法} http://www.cnblogs.com/konjak/p/5950919.html
注意——真心初始化要很小心啊!分类讨论最保险了!
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 #define N 55 7 8 int f[N][N],g[N][N]; 9 10 int main() 11 { 12 int n,k,i,j; 13 while (~scanf("%d%d",&n,&k)) 14 { 15 for (i=1;i<=n;i++) 16 { 17 f[i][1]=1; 18 for (j=2;j<=k;j++) 19 { 20 if (i<j) f[i][j]=0; 21 if (i==j) f[i][j]=1; 22 if (i>j) f[i][j]=f[i-1][j-1]+f[i-j][j]; 23 } 24 } 25 printf("%d ",f[n][k]); 26 27 for (i=1;i<=n;i++) 28 { 29 g[i][1]=(i==1)?1:0; 30 for (j=2;j<=n;j++) 31 { 32 if (i<j) g[i][j]=g[i][i]; 33 if (i==j) g[i][j]=g[i][j-1]+1; 34 if (i>j) g[i][j]=g[i][j-1]+g[i-j][j-1]; 35 } 36 } 37 printf("%d ",g[n][n]); 38 39 for (i=1;i<=n;i++) 40 { 41 f[i][1]=(i%2),g[i][1]=(i%2==0); 42 f[i][0]=f[i][1]; 43 for (j=2;j<=n;j++) 44 { 45 if (i<j) f[i][j]=g[i][j]=0; 46 if (i==j) f[i][j]=1,g[i][j]=0; 47 if (i>j) 48 { 49 f[i][j]=f[i-1][j-1]+g[i-j][j]; 50 g[i][j]=f[i-j][j]; 51 } 52 f[i][0]+=f[i][j]; 53 } 54 } 55 /*另一种简洁一点的打法,但我觉得若不能保证对就不要打这样的,不太保险... 56 f[0][0]=1; g[0][0]=1; 57 for(int i=1; i<=n; i++) 58 for(int j=1; j<=i; j++) 59 { 60 g[i][j] = f[i-j][j]; 61 f[i][j] = g[i-j][j] + f[i-1][j-1]; 62 } 63 */ 64 printf("%d ",f[n][0]); 65 } 66 return 0; 67 }