这题背包要记录路径,然后自己写了一个,感觉有点繁琐
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 }