这题是参考前辈的成果得到的,说来惭愧,居然花了一个下午才理解
记录一下。
dp是如此的强大,但要有很强的逻辑才能胜任,要找好不同状态之前的联系
/* * ===================================================================================== * * Filename: hdu1028.c * * Description: * * Version: 1.0 * Created: 2013年11月20日 11时22分16秒 * Revision: none * Compiler: gcc * * Author: Wenxian Ni (Hello World~), niwenxianq@qq.com * Organization: AMS/ICT * * Ignatius and the Princess III Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 10631 Accepted Submission(s): 7537 Problem Description "Well, it seems the first problem is too easy. I will let you know how foolish you are later." feng5166 says. "The second problem is, given an positive integer N, we define an equation like this: N=a[1]+a[2]+a[3]+...+a[m]; a[i]>0,1<=m<=N; My question is how many different equations you can find for a given N. For example, assume N is 4, we can find: 4 = 4; 4 = 3 + 1; 4 = 2 + 2; 4 = 2 + 1 + 1; 4 = 1 + 1 + 1 + 1; so the result is 5 when N is 4. Note that "4 = 3 + 1" and "4 = 1 + 3" is the same in this problem. Now, you do it!" Input The input contains several test cases. Each test case contains a positive integer N(1<=N<=120) which is mentioned above. The input is terminated by the end of file. Output For each test case, you have to output a line contains an integer P which indicate the different equations you have found. Sample Input 4 10 20 Sample Output 5 42 627 1 1 2 2 3 3 dp[i][j] = dp[i-1][j-1] + dp[i-j][j] 数字i中,最大的是j * ===================================================================================== */ #include <stdio.h> #include <math.h> int main() { int n; int i, j; int dp[121][122]; //dp[1][1] = 1; //dp[1][0] = 1; //dp[2][1] = 1; //dp[2][2] = 1; //dp[2][0] = 2; for(i=0;i<121;i++) { dp[i][i] = 1; } for(i=1;i<121;i++) { dp[i][122] = 0; for(j=1;j<=i;j++) { if(i != j) dp[i][j] = dp[i-j][j] + dp[i-1][j-1]; dp[i][121] += dp[i][j]; } } while(~scanf("%d",&n)) { printf("%d ",dp[n][121]); } return 0; }
这里面,用最后一位存储最后的结果,之前老是计算错误,才发现数组越界,哎,估计晚上脑子不好使了
最精华的是母函数理论和实现
f(x) = (1+x^1+x^2+...)(1+x^2+x^4+...)...
#include<iostream> using namespace std; #define N 121 int main() { unsigned long a[N],b[N]; int i,j,k; int n; while(cin>>n) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); a[0]=1; for(i=1;i<=n;i++) //第i个多项式 { for(j=0;j<=n;j++) //第i个多项式与之前的多项式相乘 { for(k=0;k*i+j<=n;k++) //具体添加到某一项中 b[k*i+j]+=a[j]; } for(k=0;k<=n;k++) { a[k]=b[k]; b[k]=0; } } cout<<a[n]<<endl; } return 0; }