贪心法解决01背包_neverfull包包[通俗易懂]

贪心法解决01背包_neverfull包包[通俗易懂]I-IHDU-3466ProudMerchants(贪心+01背包)Recently,iSeawenttoanancientcountry.Forsuchalongtime,itwasthemostwealthyand

贪心法解决01背包_neverfull包包[通俗易懂]"

I – I HDU – 3466Proud Merchants(贪心+01背包)

Recently, iSea went to an ancient country. For such a long time, it
was the most wealthy and powerful kingdom in the world. As a result,
the people in this country are still very proud even if their nation
hasn’t been so wealthy any more. The merchants were the most typical,
each of them only sold exactly one item, the price was Pi, but they
would refuse to make a trade with you if your money were less than Qi,
and iSea evaluated every item a value Vi. If he had M units of money,
what’s the maximum value iSea could get?

Input There are several test cases in the input.

Each test case begin with two integers N, M (1 ≤ N ≤ 500, 1 ≤ M ≤
5000), indicating the items’ number and the initial money. Then N
lines follow, each line contains three numbers Pi, Qi and Vi (1 ≤ Pi ≤
Qi ≤ 100, 1 ≤ Vi ≤ 1000), their meaning is in the description.

The input terminates by end of file marker.

Output For each test case, output one integer, indicating maximum
value iSea could get.

Sample Input
2 10
10 15 10
5 10 5
3 10
5 10 5
3 5 6
2 7 3
Sample Output
5
11

思路

  • 题意:这一题跟01背包很相似只是多了一个限制条件q,题目给力n件物品,手里有m元,每件物品有三个参数 p 、 q 、 v a l p、q、val pqval分别表示 价格、期望、价值,如果你想买某个价格为p的物品,那之后手里的钱大于等于q的时候你才可买它,问在手里有m元的情况下最多可以 买到的最大价值是多少。

  • 分析:

  1. 自己确实理解的不太好,结合Dalao的思路说一下理解吧,这一题就排序难理解,我就说关于排序的问题,加入我们有两个物品 第一件物品p = 5,q = 7,第二件物品 p = 5,q = 9,如果我们先判读第dp一个物品那么之后手里的钱为 7 , 8 , 9…. 7,8,9…. 7,8,9....时才能进行状态转移,从而借助之前 d p [ 7 − 7 ] , d p [ 8 − 7 ] , d p [ 9 − 7 ] . . . dp[7-7],dp[8-7],dp[9-7]… dp[77],dp[87],dp[97]...的状态,如果我们先dp第二个物品,当手里的手里的钱为 9 , 10 , 11…. 9,10,11…. 91011....时才能进行状态转移,从而借助之前 d p [ 9 − 7 ] , d p [ 10 − 7 ] , d p [ 11 − 7 ] . . . dp[9-7],dp[10-7],dp[11-7]… dp[97],dp[107],dp[117]...的状态,如果第一个物品先被dp 的话,当我们dp第二个物品的时候,我们是可以 借助第一件物品dp之后获得的状态的,反之则不行了,
  2. 可是在这一题中物品的价格不一定是相同的,我们仍然假设有两个物品A p1,q1、B p2,q. 如果我们要卖这个两个物品如果我们先买A,则手里的前至少要是 p1 + q2的钱(的背包容量)、如果先买B在买A,则手里的钱至少要 p2 + q1的钱(的背包容量),假设 p 1 + q 2 > p 2 + q 1 p1+q2>p2+q1 p1+q2>p2+q1的话,我们就先卖A再买B(这里有个难理解,我们先买A再买B,在dp过程中表示为,让B物品先被dp,之后A物品在被dp,正好我们dpA的时候其实就是在判断A是否要选,而判断依据我们要借助dp 物品B的时候得到的状态),公式可以转化为 p 1 − q 1 > p 2 − q 2 p1-q1>p2-q2 p1q1>p2q2,就按这个方法 p − q p-q pq小的放在前边先被dp,后被选
  • 实在理解不了就记着吧

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define ll long long 
#define mod int(1e9 + 7) //这里不要忘了加括号
#define rl rt << 1
#define rr rt << 1 | 1
const int mxn = 5005;
struct Item
{ 
   
    int p, q, val;
    int c;
    bool operator <(const Item a) const 
    { 
   
        return c < a.c;
    }
} item[mxn];

int dp[mxn];


int main()
{ 
   
    /* freopen("A.txt","r",stdin); */
    /* freopen("Ans.txt","w",stdout); */
    int n, m;
    while(~ scanf("%d %d", &n, &m))
    { 
   
        for(int i = 1; i <= n; i ++)
            scanf("%d %d %d", &item[i].p, &item[i].q, &item[i].val), item[i].c = item[i].q - item[i].p;
        sort(item + 1, item +1 + n);
        memset(dp, 0, sizeof(dp));

        for(int i = 1; i <= n; i ++)
            for(int j = m; j >= item[i].q; j --)
                dp[j] = max(dp[j], dp[j - item[i].p] + item[i].val);
        printf("%d\n", dp[m]);
    }

    return 0;
}

今天的文章贪心法解决01背包_neverfull包包[通俗易懂]分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/62997.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注