题目描述
解法:排序+0-1背包问题
先解释怎么处理最低交易价格 的问题:
示例1
3 10
5 10 5 (commodity A)
3 5 6 (commodity B)
2 7 3
如果我们先买A商品再买B商品,则总价值为11;如果先买B商品,那么下一次就不可以购买A上品了,故说明最低交易价格主要体现在购买顺序的问题上。
假设有商品A、B,其对应的数据分别为 和 ,如果先买A再买 B,那么至少需要 的金钱;如果反过来则至少需要 的金钱。我们再假设此时的购买顺序为先A后B这样花的钱最少,那么有不等式 ,即 . 那么也就说 大的商品应该优先购买,于是我们就按照 的值先对商品进行一个排序。
接着我们思考一个问题: 大的商品先购买,那么排序应该是按照 的值从小到大,还是从大到小呢?在0-1背包问题中,是倒序枚举,故排序时应该按照从小到大的顺序,这样就保证了 大的商品先购买
最后,在 的循环里面,我们应该将 改为 ,因为这样既满足了最低交易价格也满足有充足的的金钱买下物品
#include <iostream>
#include <algorithm>
using namespace std;
struct commodity{
int p, q, v;
};
bool cmp(commodity a, commodity b)
{
return a.q-a.p<b.q-b.p;
}
int main()
{
int n, m;
while(~scanf("%d%d", &n, &m))
{
commodity com[505] = {0};
int dp[5005] = {0};
for(int i=1;i<=n;i++)
scanf("%d%d%d", &com[i].p, &com[i].q, &com[i].v);
sort(com, com+n, cmp);
for(int i=1;i<=n;i++)
for(int j=m;j>=com[i].q;j--)
dp[j] = max(dp[j], dp[j-com[i].p]+com[i].v);
printf("%d\n", dp[m]);
}
return 0;
}