HDU 3466 - Proud Merchants

题目描述

Proud Merchants

解法:排序+0-1背包问题

先解释怎么处理最低交易价格 Q i Q_i Qi 的问题:

示例1

3 10
5 10 5 (commodity A)
3 5 6 (commodity B)
2 7 3

如果我们先买 A A A 商品再买 B B B 商品,则总价值为 11 11 11;如果先买 B B B 商品,那么下一次就不可以购买 A A A 商品了,故说明最低交易价格主要体现在购买顺序的问题上

假设有商品 A 、 B A、B AB,其对应的数据分别为 P a 、 Q a P_a、 Q_a PaQa P b 、 Q b P_b、Q_b PbQb,如果先买 A A A 再买 B B B,那么至少需要 P a + Q b P_a+Q_b Pa+Qb 的金钱;如果反过来则至少需要 P b + Q a P_b+Q_a Pb+Qa 的金钱

我们再假设此时的购买顺序为先 A A A B B B 这样花的钱最少,那么有不等式 P a + Q b > P b + Q a P_a+Q_b > P_b+Q_a Pa+Qb>Pb+Qa,即 P a − Q a > P b − Q b P_a-Q_a>P_b-Q_b PaQa>PbQb

那么也就说 P − Q P-Q PQ 大的商品应该优先购买,于是我们就按照 P − Q P-Q PQ 的值先对商品进行一个排序

接着我们思考一个问题: P − Q P-Q PQ 大的商品先购买,那么排序应该是按照 P − Q P-Q PQ 的值从小到大,还是从大到小呢?

在 0-1 背包问题中,是倒序枚举,故排序时应该按照从小到大的顺序,这样就保证了 P − Q P-Q PQ 大的商品先购买

最后,在 j j j的循环里面,我们应该将 j > = v o l u m e [ i ] j>=volume[i] j>=volume[i] 改为 j > = c o m [ i ] . Q j>=com[i].Q j>=com[i].Q,因为这样既满足了最低交易价格也满足有充足的的金钱买下物品

#include <iostream>
#include <algorithm>
#include <vector>
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 c[505] = {0};
        vector<int> dp(5005, 0);
        for(int i=1;i<=n;i++)
            scanf("%d%d%d", &c[i].p, &c[i].q, &c[i].v);
        sort(c, c+n, cmp);
        for(int i=1;i<=n;i++)
            for(int j=m;j>=c[i].q;j--)
                dp[j] = max(dp[j], dp[j-c[i].p]+c[i].v);
        printf("%d\n", dp[m]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值