题目描述 马上要“六一”儿童节了,女儿吵着让爸爸买礼物。可女儿要买的东西实在太多了,爸爸手头上只有M元钱,觉得可能不能全部满足她,但是他又希望女儿尽量开开心心的。爸爸看了女儿的礼物单,上面有N件礼物,查到了所有礼物的价格,以及买给她会女儿开心度增加的值和不买给她开心度减少的值(每种礼物只能买1个)。他想知道开心度最大是多少,希望你能帮帮他。 输入 存在多组测试数据 输出 每个样例输出1行,为最大的开心度。 样例输入 3 100 30 10 5 80 20 16 60 15 7 3 100 30 10 5 70 20 16 60 15 6 0 0 样例输出 9 24 |
此题属于01背包类问题,我的思路是从所有礼物都无法买到的负开心度开始,若能购买某件礼物则应该增加 购买礼物增加的开心度和不买礼物减少的开心度 之和,然后使用动态规划的方法找出开心度最大值。
具体代码如下:
//礼物
#include<stdio.h>
#include<string.h>
int max(int a, int b)
{
if (a > b)
return a;
else
return b;
}
int main()
{
int n, m,i,j;
int dp[20][1005] = { 0 };
int p[20] = { 0 };
int ii[20] = { 0 };
int d[20] = { 0 };
while (scanf("%d %d", &n, &m) != EOF)
{
int sum = 0;
if (n == 0 && m == 0)
break;
for (i = 1; i <= n; i++)
{
scanf("%d %d %d", &p[i], &ii[i], &d[i]);
ii[i] += d[i];
sum -= d[i];
}
for (i = 1; i <= n; i++)
for (j = 1; j <= m; j++)
{
dp[i][j] = dp[i - 1][j];//不放
if (j >= p[i])
dp[i][j] = max(dp[i][j], dp[i - 1][j - p[i]] + ii[i]);
//放
}
sum += dp[n][m];
printf("%d\n", sum);
memset(dp, 0, sizeof(dp));
}
return 0;
}
动态规划解决背包问题的思路在这里给出下面链接:
https://blog.csdn.net/qq_38410730/article/details/81667885?spm=1001.2014.3001.5506
其实对于该动态规划方法也可以从二维数组优化到一维数组
具体代码如下:
#include<stdio.h>
#include<string.h>
int max(int a, int b)
{
if (a > b)
return a;
else
return b;
}
int main()
{
int n, m, i, j;
int dp[1005] = { 0 };
int p[20] = { 0 };
int ii[20] = { 0 };
int d[20] = { 0 };
while (scanf("%d %d", &n, &m) != EOF)
{
int sum = 0;
if (n == 0 && m == 0)
break;
for (i = 1; i <= n; i++)
{
scanf("%d %d %d", &p[i], &ii[i], &d[i]);
ii[i] += d[i];
sum -= d[i];
}
for (i = 1; i <= n; i++)
for (j = m; j >=p[i] ; j--)
{
dp[j] = max(dp[j], dp[j - p[i]] + ii[i]);
}
sum += dp[m];
printf("%d\n", sum);
memset(dp, 0, sizeof(dp));
}
return 0;
}
这个优化到一维数组的思路是参考的以下链接:
https://blog.csdn.net/qq_42174306/article/details/123535122?spm=1001.2014.3001.5506
萌新第一次发CSDN,还请大佬们多多指教哈~