题目大意:
第一行输入两个整数,第一个是物品的种类的数量N,第二个是你手里持有的钱数M,然后底下再输入N行,每行包括3个整数p(物品的标价),q(买这一件商品你手里需要的最少钱数),v(这件商品能带给你的价值)。编程输出在手里持有钱数的范围内,即在经济范围内买的东西的最大价值。
解题思路:
乍一看这道题觉得像是一道01背包,其实这道题勉强可以说是一道01背包的问题。但是01背包问题与物品的顺序无关,而这个问题的答案与购买物品的顺序有着莫大的关系。买一件东西的时候能否可以买取决于手中持有的钱数,而这钱数并不是是否大于等于这件商品的价格,这个钱数要远大于商品的价格。这就牵扯到给物品的排序问题,而排序的依据呢????我就是以q-p的差价作为排序的标准来给物品排序,这样就是一道01背包问题,能用手里的钱买到最大价值的东西。01背包的状态转移方程:bag[j]=max(bag[j],bag[j-cos[i]]+val[i])。
代码如下:
#include<stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define max(a,b) (a>b?a:b)
struct Shopping
{
int price;
int least;
int desert;
};
int cmp(Shopping a, Shopping b)
{
return (a.least - a.price)<(b.least - b.price);
}
int main()
{
int bag[5001];
Shopping sp[5001];
int number, money;
while (cin >> number)
{
cin >> money;
for (int i = 1; i <= number; i++)
{
cin >> sp[i].price;
cin >> sp[i].least;
cin >> sp[i].desert;
}
memset(bag, 0, sizeof(bag));
sort(sp + 1, sp + number + 1, cmp);
for (int i = 1; i <= number; i++)
{
for (int j = money; j >= sp[i].least; j--)
{
bag[j] = max(bag[j], bag[j - sp[i].price] + sp[i].desert);
}
}
cout << bag[money] << endl;
}
return 0;
}