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;
}

 

posted @ 2013-01-31 13:14  'wind  阅读(287)  评论(0编辑  收藏  举报