HDU 1284 钱币兑换问题
题意:
在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法。请你编程序计算出共有多少种兑法。
分析:
可以用母函数,也可以用DP
dp[n][m]表示钱n用前m种硬币的兑换方式
[ 1 m = 1;
dp(n, m) = [ dp(n, n) n < m;
[ 1 + dp(n, n-1) n = m;
[ dp(n, m-1) + dp(n-m, m) n > m > 1.
dp_记忆化搜索
#include <stdio.h> #include <string.h> int dp[32769][4]; int dfs(int n,int m) { if (dp[n][m]) return dp[n][m]; if (m==1) return 1; if(n<m) { return dp[n][m] = dfs(n,n); } if(n==m) { return dp[n][m] = 1+dfs(n,n-1); } if(n>m) { return dp[n][m]=dfs(n-m,m)+dfs(n,m-1); } } void init() { memset(dp,0,sizeof(dp)); } int main() { init(); int n; while (scanf("%d",&n)!=EOF) { printf("%d\n",dfs(n,3)); } return 0; }
母函数
#include <stdio.h> #include <string.h> const int maxn = 32768; int c1[32769]; int c2[32769]; int main() { int i,j,k; for (i=0; i<maxn; i++) { c1[i] = 0; c2[i] = 1; } for (i=0;i<maxn; i++) { for (j=0;i+j<maxn; j+=2) c1[i+j]+=c2[i]; } for (i=0; i<maxn; i++) { c2[i] = c1[i]; c1[i] = 0; } for (i=0; i<maxn; i++) { for (j=0;i+j<maxn; j+=3) { c1[i+j] += c2[i]; } } int n; while (scanf("%d",&n)!=EOF) { printf("%d\n",c1[n]); } return 0; }