4种钱币,价值是1 5 10 25,给你他们的个数,问能不能用最多的钱币到达p,如果能输出每种的个数,不能输出不能。。
开个numb二维数组记录路径。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int numb[11000][4],dp[20000],ci[4],p,wi[4];
void complete(int cost,int it){
for(int j=cost;j<=p;j++){
if(dp[j]<dp[j-cost]+1&&dp[j-cost]){
dp[j]=dp[j-cost]+1;
for(int i=0;i<4;i++){
numb[j][i]=numb[j-cost][i];
}
numb[j][it]+=1;
}
}
}
void zeroone(int cost,int num,int it){
for(int j=p;j>=cost;j--){
if(dp[j]<dp[j-cost]+num&&dp[j-cost]){
dp[j]=dp[j-cost]+num;
for(int i=0;i<4;i++){
numb[j][i]=numb[j-cost][i];
}
numb[j][it]+=num;
}
}
}
int main(){
wi[0]=1;wi[1]=5;wi[2]=10;wi[3]=25;
while(scanf("%d%d%d%d%d",&p,&ci[0],&ci[1],&ci[2],&ci[3])&&p){
memset(numb,0,sizeof(numb));
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=0;i<4;i++){
if(ci[i]*wi[i]>=p){
complete(wi[i],i);
}
else{
int ki=1,amount=ci[i];
while(ki<amount){
zeroone(wi[i]*ki,ki,i);
amount-=ki;
ki*=2;
}
zeroone(amount*wi[i],amount,i);
}
}
if(dp[p]==0){
printf("Charlie cannot buy coffee.\n");
}
else{
printf("Throw in %d cents, %d nickels, %d dimes, and %d quarters.\n",numb[p][0],numb[p][1],numb[p][2],numb[p][3]);
}
}
return 0;
}