题目链接:(—_—) 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;
}
code:一维
#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;
}