Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 4505 | Accepted: 1420 |
Description
Input
Output
Sample Input
12 5 3 1 2 16 0 0 0 1 0 0 0 0 0
Sample Output
Throw in 2 cents, 2 nickels, 0 dimes, and 0 quarters. Charlie cannot buy coffee.
#include
#include
using namespace std;
int dp[10005], used[10005], pre[10005], coin[4] = {1, 5, 10, 25}, num[4], ans[26];
int main(){
int p;
while(scanf("%d %d %d %d %d", &p, &num[0], &num[1], &num[2], &num[3]) != EOF){
if(p + num[0] + num[1] + num[2] + num[3] == 0) return 0;
for(int i = 0; i <= p; ++i){
dp[i] = -1e9;
}
memset(pre, 0, sizeof(pre));
pre[0] = -1;
dp[0] = 0;
for(int i = 0; i < 4; ++i){
memset(used, 0, sizeof(used));
for(int j = coin[i]; j <= p; ++j){
if(dp[j] < dp[j - coin[i]] + 1 && used[j - coin[i]] < num[i]){
used[j] = used[j - coin[i]] + 1;
dp[j] = dp[j - coin[i]] + 1;
pre[j] = j - coin[i];
}
}
}
if(dp[p] <= 0){
printf("Charlie cannot buy coffee.\n");
continue;
}
memset(ans, 0, sizeof(ans));
while(1){
if(pre[p] == -1) break;
ans[p - pre[p]]++;
p = pre[p];
}
printf("Throw in %d cents, %d nickels, %d dimes, and %d quarters.\n", ans[1], ans[5], ans[10], ans[25]);
}
}
/*
题意:10000元,4种面值硬币,给出每种硬币的个数,问最多可以用多少个硬币组合成给定的总价格,输出方案。
思路:就是完全背包需要输出方案,dp[j]表示总价格为j时最多可以有多少个硬币,但是需要维护一下硬币的个数,
实际上在01背包中,我们对所有状态都更新了一次答案,这里我们等于是对4种硬币各跑一次背包,维护一下使用
次数即可。used[j]表示总价格为j时用了多少个某个硬币。pre[j]记录方案,表示j出现更有的答案时是由哪个状态
转移来的。
最后遍历一下输出答案就好了。这里不能滚动数组来做,因为硬币不止1个,滚动只更新了一次答案。
*/