hdu 3466 Proud Merchants <背包+sort排序>

Proud Merchants

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)

Total Submission(s): 3616    Accepted Submission(s): 1511

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 10
10 15 10
5 10 5
3 10
5 10 5
3 5 6
2 7 3

Sample Output

5
11

Author

iSea @ WHU

题意:

首先输入n,m两个数;n代表物品的个数,m代表总共的钱数;接下来输入n行,每行3个数,第一个数是商品的标价,第二个数是卖家要求你手里面最少有的钱数才能购买人家的商品,第3个数是你认为这个商品的价值是多少;最终让你求用你手里面的m元钱购买商品使你手里面所得到(你认为的)价值最大!

思路:

这道题和一般的01背包不一样,因为一般的01背包与装物品的顺序无关,所以我们就能直接01背包去做,而这道题因为涉及到要买某个东西,首先手里面要有多少的钱的限制,有时候虽然你的钱能够买这两个物品,但是就是因为你购买的顺序不对,所以造成你只能购买一件,另一件不能购买!

例如:A:p1=5, q1=10, v1=5;

B:p2=3, q2=5,  v2=6;

如果你手里面有10块钱,你先购买A再购买B,你会买到价值为11元的东西,如果你先买B的话你就只能购买一件商品了,所以这道题不能用01背包直接做!

怎样我们才能更好的控制一下,如果A,B两个商品都买的话就只能先买A再买B呢?怎样才能按照这样的顺序进行购买商品,使买到的商品的价值最大呢?首先我们先就上面这个例子进行分析看看只有满足怎样的购买顺序才能使能购买的商品不因为顺序的原因而被迫不买!

仍然以上面的这个例子为例进行分析:如果先买物品A再买物品B的话我至少需要10元钱,如果先买物品B再买物品A的话,我们至少需要13元钱,也就是得到相同的价值的物品,我们却需要两个不同价值的钱,当然我们选择要花少的钱购买相同价值的商品了!这两个价值满足p1+q2<p2+q1(为了使数据满足一定的顺序进行购买,因此我们使所有的数据都按照(q1-p1>q2-p2)这样的顺序排序,这样购买最终我们所需的钱数就是最少的,也就是拿同样多的钱,我们可以买更大价值的东西!在这里p1+q2<p2+q1与q1-p1>q2-p2等价,只不过在这里我们将描述同一个物体的变量放到不等式的一边(q1-p1>q2-p2),然后再进行排序操作比较方便罢了),如果我们都按照这样的顺序(qi-pi从大到小的顺序)进行排序,

先买差值大的物品再买差值小的物品,也就是要是买的话肯定是按照先A后B的顺序,这样我们就不会因为顺序的原因而少买东西!然后我们再根据01背包将能够购买的最大的价值的物品全部购买,就得到我们要求的最大的价值了!

但是,我们还有以点没有考虑,那就是我们知道先选大的差值(qi-pi)去买,那么01背包是怎么操作呢?(bag[j]=max(bag[j],bag[j-cos[i]]+val[i]))

其实01背包的购买都是按照从后向前的顺序进行购买的,也就是说,它的每次的最后一个商品是确定购买的,然后再加上前面的除下用的最后一个的钱之后能够够购买的最大的价值与不购买这个物品进行比较,哪个大就选哪个!(在这个过程中因为是先确定后面的物品是否购买,所以我们要将差值(qi-pi)大的放到后面,差值小的放到前面,也就是前面说的按照从大到小的顺序是进行购买的顺序,而真正排序,然后按照背包执行程序的时候是按照从小到大的顺序!)

总之,就是按照差值(qi-pi)从小到大排序,然后用01背包的方法进行操作就行了!

AC代码:

//艰难的做了一道题,排序真难理解!
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define max(a,b) (a>b?a:b)
using namespace std;
struct inin
{
	int p;
	int q;
	int v;
}a[550];
int bag[5005];
int cmp(inin a,inin b)//这一点一定要记住排序!
{
	return (a.q-a.p)<(b.q-b.p);
}
int main()
{
	int n,m;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(bag,0,sizeof(bag));
		for(int i=1;i<=n;i++)
		{
			scanf("%d%d%d",&a[i].p,&a[i].q,&a[i].v);
		}
		sort(a+1,a+n+1,cmp);
		for(int i=1;i<=n;i++)
		{
			for(int j=m;j>=a[i].q;j--)
			{
				bag[j]=max(bag[j],bag[j-a[i].p]+a[i].v);
			}
		}
		printf("%d\n",bag[m]);
	}
	return 0;
} 

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-13 13:32:07

hdu 3466 Proud Merchants <背包+sort排序>的相关文章

hdu 3466 Proud Merchants(0-1背包+排序)

题目来源:hdu 3466 Proud Merchants Proud Merchants Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 3595 Accepted Submission(s): 1500 Problem Description Recently, iSea went to an ancient country. For

hdu 3466 Proud Merchants(有排序的01背包)

Proud Merchants Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 4039    Accepted Submission(s): 1677 Problem Description Recently, iSea went to an ancient country. For such a long time, it was

HDU 3466 Proud Merchants(01背包)

这道题目看出背包很容易,主要是处理背包的时候需要按照q-p排序然后进行背包. 这样保证了尽量多的利用空间. Proud Merchants Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 2674    Accepted Submission(s): 1109 Problem Description Recently, iSea we

HDU 3466 Proud Merchants(0-1背包)

http://acm.hdu.edu.cn/showproblem.php?pid=3466 题意: 最近,iSea去了一个古老的国家.在这么长的时间里,它是世界上最富有和最强大的王国.结果,这个国家的人民仍然非常自豪,即使他们的国家没有那么富有了.商人是最典型的,每个人只卖一个项目,价格是Pi,但如果你的钱少于Qi,他们会拒绝与你交易,iSea评估每个项目一个值Vi.如果他有M单位的钱,iSea可以获得的最大价值是多少? 思路: 这道题的话多加了一个Qi. 一定要注意,若要保证动归方程无后效性

hdu 3466 Proud Merchants 自豪的商人(01背包,微变形)

题意: 要买一些东西,每件东西有价格和价值,但是买得到的前提是身上的钱要比该东西价格多出一定的量,否则不卖.给出身上的钱和所有东西的3个属性,求最大总价值. 思路: 1)WA思路:与01背包差不多,dp过程中记录每个容量所能获得的最大价值以及剩余的容量.实现是,开个二维dp数组,从左往右扫,考虑背包容量为j的可获得价值量,根据该剩余容量得知要更新后面哪个背包容量[j+?] ,如果剩余容量大于q[i]那么可以直接装进去,更新价值以及剩余容量,否则,考虑更新的是更大的背包容量.这个思路有缺陷,一直找

hdu 3466 Proud Merchants 【限制性01背包】

题目链接:https://vjudge.net/contest/103424#problem/J 转载于:https://www.bbsmax.com/A/RnJW16GRdq/ 题目大意: 有n个商品m块钱,给出买每个商品所花费的钱P.钱包里需要至少Q才有资格买.商品的价值V.问你如何购买商品的价值最大. 解题分析:考虑下面的例子:A:p1=5, q1=10, v1=5; B:p2=3, q2=5, v2=6; 如果先买物品A再买物品B的话我至少需要10元钱,也就是money >= p1+q2

【HDOJ】3466 Proud Merchants

先排序预处理,后01背包. 1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 #define MAX(a, b) (a>b) ? a:b 6 7 int dp[5000]; 8 9 typedef struct { 10 int p, q, v; 11 } stuff_st; 12 13 stuff_st stuffs[505]; 14 15 int comp(const vo

01背包水题篇之HDU3466——Proud Merchants

这是个好题,菜鸟刚学dp,这题把我以前的想法全都给完完全全的颠覆了.其实是自己没了解无后效性的概念. 然后我去开开心心滴跑去问队长:"队长,队长,怎么理解动归的无后效性啊???" 学长很深沉滴对我说:"做多了就会了" "噢噢"(好吧) 然后学长又补了句:"能构成有向无环图的都能用DP搞." 我心里想:"队长就知道搞妹~~~." 默默去翻小白书看看DAG去了. 为了搞清楚这题怎么写,操了度娘千百遍,还是没搞定

HDU3466 Proud Merchants[背包DP 条件限制]

Proud Merchants Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 5599    Accepted Submission(s): 2362 Problem Description Recently, iSea went to an ancient country. For such a long time, it was