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