HDU3466 Proud Merchants(贪心+01背包)

来源:互联网 发布:排序算法中空间复杂度 编辑:程序博客网 时间:2024/06/06 12:57

题目:

Proud Merchants

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 6166    Accepted Submission(s): 2549


Problem Description
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 1010 15 105 10 53 105 10 53 5 62 7 3
 

Sample Output
511
 

Author
iSea @ WHU
 

Source
2010 ACM-ICPC Multi-University Training Contest(3)——Host by WHU
 

Recommend
zhouzeyong   |   We have carefully selected several similar problems for you:  3460 3463 3468 3467 3465 
 
思路:

先说一下题意,有n个物品,你拥有的总钱数是m.你要买东西,接下来n组数据每组数据有三个数p代表这个物品的价格,q代表如果你的钱数少于q你就不能买这个东西,v代表这一件物品的价值,问的是你最多能得到多少价值的物品。

我们的做法是先对每个物品的(q-p)从小到大排序,然后按照01背包的方式来做。

因为q一定大于p,所以不用担心q-p的值会小于0.而问题来了,为什么要对q-p进行排序呢

我们用一组样例来分析一下。

2 10

5  8 5

2  7  3

如果我们先买A物品,花费5元还剩五元,但是剩余的钱是5元不够7元,所以我们得到的最大价值,只能是5.

但是如果先买B物品的话,先花费2元,剩余8元,然后再买第一件物品,最后可以得到的最大价值是5+3=8.

用p1,q1,p2,q2来表示这两组数据的话,你要买这两个物品的话,如果先买第2个那么你要有的钱数是p2+q1或者p1+q2.很明显,在这里p1+q2>p2+q1,把它们进行移项得到:

q2-p2>q1-p1,所以我们得到的策略是,先选q-p的值比较大的,也就是从大到小排列,但是按照01背包做的话,01背包的本质是先总后面往前取,所以我们按照q-p从小到大排序的话,01背包从后面往前取,正好符合我们从大到小取得思想,所以我们要先排序,后按照01背包做


比赛的时候,感觉这是贪心,又像01背包,但是都没做出来,还是看了大牛的思想才会的。。

参考博客:http://blog.csdn.net/oceanlight/article/details/7866759

代码:

#include <stdio.h>#include <string.h>#include <string>#include <iostream>#include <stack>#include <cmath>#include <queue>#include <vector>#include <algorithm>#define mem(a,b) memset(a,b,sizeof(a))#define inf 0x3f3f3f3f#define N 500+20#define M 1000000+10#define LL long longusing namespace std;int n,m,dp[50000];struct node{    int p;//价格    int q;//钱数小于q就不能买    int v;//价值} g[N];bool cmp(node x,node y){    return (x.q-x.p)<(y.q-y.p);}int main(){    while(~scanf("%d%d",&n,&m))    {        mem(dp,0);        for(int i=0; i<n; i++)            scanf("%d%d%d",&g[i].p,&g[i].q,&g[i].v);        sort(g,g+n,cmp);        for(int i=0; i<n; i++)        {            for(int j=m; j>=g[i].q; j--)            {                dp[j]=max(dp[j],dp[j-g[i].p]+g[i].v);            }        }        printf("%d\n",dp[m]);    }    return 0;}


0 0