这位大佬的博客代码特别精简先留坑,日后再补
//dp[i]: 为真表示能够组成i钱数
//path[p][j]: 表示组成j钱数,p种硬币被用的次数
#include
#include
#include
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;
}