提交人:侯建鹏
提交日期:2012/4/16
1002 Ignatius and the Princess III
解题思路(一):动态规划
先设置int p[N][N];
Dp 方程为:p[i][j]=p[i][j-1]+p[i-j][j]。
其中,p[i][j]表示将i分解成小于等于j个项的方法的种数。很明显,p[i][j]等于将i分解成小于等于j-1个项的种数(即p[i][j-1]),再加上,将它分解成j个项的方法的种数(即p[i-j][j]).
下面重点来说一下为什么将i分解成j个项的方法的种数为p[i-j][j]。
举例:将4分解成2个项的方法有两种,3、1和2、2.将这两组数字每个数字都减一,你会发现这两组数字变成了2、0和1、1,把0省略掉,即写成2和1、1,这恰好是把2分解成小于等于两个项的方法数。
所以,你可以清楚的发现,i分解成j个项的方法的种数即为将i-j分解成小于等于j个项的方法种数,即p[i-j][j].
当然,还有一些其他问题需要注意,不过就很简单了,详见程序。
#include<stdio.h> #define N 130 int p[N][N]; int main() { for(int i=0;i<N;i++) { p[0][i]=1;p[1][i]=1;p[i][1]=1; } for(i=2;i<N;i++) for(int j=2;j<N;j++) if(j<=i) p[i][j]=p[i][j-1]+p[i-j][j]; else p[i][j]=p[i][j-1]; int n; while(scanf("%d",&n)==1) printf("%d\n",p[n][n]); return 0; }
解题思路(二):母函数
我感觉其实就是特殊的动态规划,计算(1+x+x^2+x^3+……)*(1+x^2+x^4+x^6+……)*(1+x^3+x^6+x^9+……)*……中最后x^n前面的系数。详见代码。
#include<stdio.h> #define N 122 int main() { int a[N],b[N],i,j,k,n; for(i=0;i<N;i++) { a[i]=1; b[i]=0; } for(i=2;i<N;i++) { for(k=0;k<N;k+=i) for(j=0;j+k<N;j++) b[j+k]+=a[j]; for(j=0;j<N;j++) { a[j]=b[j]; b[j]=0; } } while(scanf("%d",&n)==1) printf("%d\n",a[n]); return 0; }