Charlie's Change POJ - 1787 (完全背包+记录路径)

完全背包输出路径;对于每一次更新记录一下路径;注意钱币个数;

dp[i][0]代表在空间为i时需要多少枚钱币

dp[i][1]用来记录路径

cheek[j]用来记录在j时用了多少i枚钱币

思路在代码中;

  

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

#define mem(a,b) memset(a,b,sizeof(a))

int dp[10010][2],b[10]= {0,1,5,10,25};

int mub[10],cheek[10010],ans[10010];

int n;

int main()
{
    while(scanf("%d",&n))
    {
        int f=0;
        for(int i=1; i<=4; i++)
        {
            scanf("%d",&mub[i]);
            if(mub[i]==0) f++;
        }
        if(f==4&&!n) break;
        mem(dp,0);
        
        for(int i=1; i<=4; i++)
        {
            mem(cheek,0);
            for(int j=b[i]; j<=n; j++)
            {
                if(dp[j-b[i]][0]+1>dp[j][0]&&cheek[j-b[i]]+1<=mub[i]&&(j==b[i]||dp[j-b[i]][0]))//&&(j==b[i]||!dp[j][0]))
                                                                    //保证这次状态是从上一次合法状态推过来的
                {
                    dp[j][0]=dp[j-b[i]][0]+1;//记录钱币数
                    dp[j][1]=j-b[i];//记录路径
                    cheek[j]=cheek[j-b[i]]+1;//记录使用多少i枚钱币,防止超出
                }
            }
        }
        
        mem(ans,0);
        int i=n;
        if(!dp[n][ 0]) printf("Charlie cannot buy coffee.\n");
        else 
        {
            while(i)//跑一边路径记录答案
            {
                //cout<<i<<endl;
                ans[i-dp[i][1]]++;
                i=dp[i][1];

            }
            printf("Throw in %d cents, %d nickels, %d dimes, and %d quarters.\n",ans[1],ans[5],ans[10],ans[25]);
        }
    }
    return 0;
}

 

posted @ 2019-05-22 20:30  Minun  阅读(171)  评论(0编辑  收藏  举报