题目描述
马上要“六一”儿童节了,女儿吵着让爸爸买礼物。可女儿要买的东西实在太多了,爸爸手头上只有M元钱,觉得可能不能全部满足她,但是他又希望女儿尽量开开心心的。爸爸看了女儿的礼物单,上面有N件礼物,查到了所有礼物的价格,以及买给她会女儿开心度增加的值和不买给她开心度减少的值(每种礼物只能买1个)。他想知道开心度最大是多少,希望你能帮帮他。
输入
存在多组测试数据
每组数据的第一行是两个整数N(1 ≤ N ≤ 16),M(1 ≤ M ≤ 1,000)。如果N和M为0,表示输入结束。
以后的N行,每行为一个礼物的价格P(1 ≤ P ≤ 200),买增加的开心度I(1 ≤ I ≤ 50),不买减少的开心度D(1 ≤ D ≤ 50)。输出
每个样例输出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
解题思路:这题每个物品有 价格,又有相应的价值,又让我们求利益最大化。 像这类的题就是很明显的 背包问题 , 而这个题是较为简单的 0/1背包 。具体怎么写大家在CSDN上搜一下。
AC代码:
#include <stdio.h>
#include <stdlib.h>
struct GIFT{ // 结构体
int price,happy,sad;
}gift[20];
int Max(int x,int y){
if (x <= y) return y;
return x;
}
int main()
{
int N,M,unhappy;
while (scanf("%d %d",&N,&M) != EOF && !(N==0 && M==0))
{
unhappy = 0;
int value[18][1012] = {0};
for (int i = 1; i <= N; i ++) // 输入
{
scanf("%d %d %d",&gift[i].price,&gift[i].happy,&gift[i].sad);
unhappy += gift[i].sad;
}
// 初始化,我这里是从最大不开心度往下减的,可以算是倒着来,不习惯的可以从0开心度往上加。
for (int i = 0; i <= N; i ++) value[i][0] = -unhappy;
for (int j = 0; j <= M; j ++) value[0][j] = -unhappy;
for (int i = 1; i <= N; i ++) // 0/1背包 核心代码
{
for (int j = 0; j <= M; j ++)
{
if (j < gift[i].price)
value[i][j] = value[i-1][j];
else
value[i][j] = Max(value[i-1][j],value[i-1][j-gift[i].price]+gift[i].happy+gift[i].sad);
}
}
printf("%d\n",value[N][M]);
}
return 0;
}