POJ 1787 Charlie's Change

这题背包要记录路径,然后自己写了一个,感觉有点繁琐

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<set>
  6 #include<vector>
  7 #include<map>
  8 #include<algorithm>
  9 #include<cmath>
 10 #include<stdlib.h>
 11 using namespace std;
 12 int need,p[4],dp[10010],pe[4]={1,5,10,25},from[10010],add[10010],way[10010];
 13 void allpack(int cost)
 14 {
 15     for(int i=cost;i<=need;i++)
 16     if(dp[i-cost]!=0||i-cost==0){
 17          if(dp[i]<dp[i-cost]+1){
 18           from[i]=i-cost;//记录从哪个位置过来
 19           way[i]=cost;   
 20           add[i]=cost;   //记录转过来时的方法
 21          }
 22          dp[i]=max(dp[i],dp[i-cost]+1);
 23     }
 24 
 25 }
 26 void zeropack(int cost,int num)
 27 {
 28     for(int i=need;i>=cost;i--)
 29     if(dp[i-cost]!=0||i-cost==0){
 30          if(dp[i]<dp[i-cost]+num){
 31           from[i]=i-cost;//记录从哪个位置过来
 32           add[i]=cost;
 33           way[i]=cost/num; //记录转过来时的方法
 34          }
 35     dp[i]=max(dp[i],dp[i-cost]+num);
 36     }
 37 
 38 }
 39 void multipack()
 40 {
 41     int i,j;
 42     for(i=0;i<4;i++){
 43         int sum=p[i]*pe[i];
 44         if(sum>=need)
 45         allpack(pe[i]);
 46         else{
 47             int k=1;
 48             while(p[i]>=k){
 49                 zeropack(pe[i]*k,k);
 50                 p[i]-=k;
 51                 k*=2;
 52             }
 53             zeropack(pe[i]*p[i],p[i]);
 54         }
 55     }
 56 }
 57 int main()
 58 {
 59     int i,j,c1,c2,c3,c4;
 60     while(cin>>need)
 61     {
 62         for(i=0;i<4;i++)
 63         cin>>p[i];
 64         if(need==0&&p[0]==0&&p[1]==0&&p[2]==0&&p[3]==0)
 65         break;
 66         memset(dp,0,sizeof(dp));
 67         memset(from,-1,sizeof(from));
 68         multipack();
 69         c1=c2=c3=c4=0;
 70         int tmp=need;
 71         if(dp[need]!=0)
 72         while(tmp){
 73             if(way[tmp]==1){
 74                 c1+=add[tmp]/1;
 75                 tmp=from[tmp];
 76                 continue;
 77             }
 78             if(way[tmp]==5){
 79                 c2+=add[tmp]/5;
 80                 tmp=from[tmp];
 81                 continue;
 82             }
 83             if(way[tmp]==10){
 84                 c3+=add[tmp]/10;
 85                 tmp=from[tmp];
 86                 continue;
 87 
 88             }
 89             if(way[tmp]==25){
 90                 c4+=add[tmp]/25;
 91                 tmp-=add[tmp];
 92                 continue;
 93             }
 94         }
 95         if(dp[need]!=0)
 96         cout<<"Throw in "<<c1<<" cents, "<<c2<<" nickels, "<<c3<<" dimes, and "<<c4<<" quarters."<<endl;
 97         else
 98         cout<<"Charlie cannot buy coffee."<<endl;
 99     }
100 }
View Code
原文地址:https://www.cnblogs.com/ainixu1314/p/3843604.html