poj 1787 Charlie's Change(多重背包转完全背包+打印路径)

这位大佬的博客代码特别精简先留坑,日后再补

//dp[i]: 为真表示能够组成i钱数
//path[p][j]: 表示组成j钱数,p种硬币被用的次数

#include   <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 10005;
const int inf = 0x3f3f3f3f;
int dp[maxn], path[5][maxn];
int v, c[5];
int a[] = {0, 1, 5, 10, 25};
int main() {
    while(~scanf("%d%d%d%d%d", &v, &c[1], &c[2], &c[3], &c[4])) {
        if(v + c[1] + c[2] + c[3] + c[4] == 0) break;
        memset(dp, 0, sizeof(dp));
        memset(path, 0, sizeof(path));
        dp[0] = 1;
        for(int i = 1; i <= 4; i++) {
            for(int j = a[i]; j <= v; j++) {
                if(dp[j - a[i]] && dp[j] < dp[j - a[i]] + 1 && path[i][j - a[i]] + 1 <= c[i]) {
                    dp[j] = dp[j - a[i]] + 1;
                    path[i][j] = path[i][j - a[i]] + 1;


                    for(int p = 1; p < i; p++) path[p][j] = path[p][j - a[i]];
                }
            }
        }
        if(dp[v] == 0)  printf("Charlie cannot buy coffee.\n");
        else printf("Throw in %d cents, %d nickels, %d dimes, and %d quarters.\n", path[1][v], path[2][v], path[3][v], path[4][v]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yiqzq/article/details/80471640