题目链接:(—_—) zZ
题目大意:有面值为1分,5分, 10分,25分的面值的硬币, 现在现在要买价格为p分的咖啡,要求求出给出的硬币数最多且和为p分的方案。
思路:dp[i][j] = max(dp[i-1][j], dp[i][j-coin[i]]), dp[i][j] 表示用第i种硬币凑成j分的用了多少硬币数
code:
#include <stdio.h> #include <string.h> int coin[5] = {0, 1, 5, 10, 25}, c[5], num[10002], pre[10002], dp[5][10002], ans[26]; int main() { int i = 0, j = 0, p = 0; while(scanf("%d %d %d %d %d", &p, &c[1], &c[2], &c[3], &c[4]) , p+c[0]+c[1]+c[2]+c[3]+c[4]) { memset(dp, 0, sizeof(dp)); memset(ans, 0, sizeof(ans)); memset(pre, 0, sizeof(pre)); for(i = 0; i<=4; i++) dp[i][0] = 1; for(i = 1; i<=4; i++) { memset(num, 0, sizeof(num));//num记录当前用这个硬币的数 for(j = 1; j<=p; j++) { if(j>=coin[i] && dp[i][j-coin[i]] && dp[i-1][j]<dp[i][j-coin[i]]+1 && num[j-coin[i]]<c[i]) { dp[i][j] = dp[i][j-coin[i]]+1; num[j] = num[j-coin[i]]+1; pre[j] = j-coin[i]; } else { dp[i][j] = dp[i-1][j]; } } } if(dp[4][p] != 0) { while(p != 0) { 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]); } else printf("Charlie cannot buy coffee.\n"); } return 0; }
#include <stdio.h> #include <string.h> int coin[5] = {0, 1, 5, 10, 25}, c[5], num[10002], pre[10002], dp[10002], ans[26]; int main() { int i = 0, j = 0, p = 0; while(scanf("%d %d %d %d %d", &p, &c[1], &c[2], &c[3], &c[4]) , p+c[0]+c[1]+c[2]+c[3]+c[4]) { memset(dp, 0, sizeof(dp)); memset(ans, 0, sizeof(ans)); memset(pre, 0, sizeof(pre)); dp[0] = 1; for(i = 1; i<=4; i++) { memset(num, 0, sizeof(num)); for(j = coin[i]; j<=p; j++) { if(dp[j-coin[i]] && dp[j-coin[i]]+1>dp[j] && num[j-coin[i]]<c[i]) { dp[j] = dp[j-coin[i]]+1; num[j] = num[j-coin[i]]+1; pre[j] = j-coin[i]; } } } if(dp[p] != 0) { while(p != 0) { 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]); } else printf("Charlie cannot buy coffee.\n"); } return 0; }