您的位置:首页 > 其它

HDU - 3466 Proud Merchants(不理解)

2015-08-08 11:18 381 查看
Proud Merchants

Time Limit: 1000MSMemory Limit: 65536KB64bit IO Format: %I64d & %I64u
Submit Status

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


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

分析:

每件物品有一个限制,只有当你当前现金大于qi的时候才会卖给你。

这题好好想了一下,跟之前做过的一道题有些类似。考虑简化版,有两个物品(p1,q1,v1),(p2,q2,v2),然后物品1先放的话,物品2就可以借助物品1产生的各种状态来进行下一步转移,而如果物品2的q2值过高,在这个[q2,m]的区间内都不存在物品1造成的新状态的话,那么物品1的状态就没有得到利用。而如果交换顺序,先放了物品2,那么显然物品1就可以利用物品2产生的新状态。

所以物品1能从物品2转移的状态区间其实是[min(q1+p2,m),m],物品2能从物品1转移的状态区间是[min(q2+p1,m),m]。所以尽可能地复用这个区间,让区间小的先来,区间大的后来,这样排序之后所有物品都能从前面的物品得到新状态进行转移。

而普通的01背包之所以不需要排序,是因为p1==q1,p2==q2,排序跟不排是一回事。这一类的dp题要注意后效性是否存在,如果存在通过改变顺序之类的办法来取消后效性。再有杭电上饭卡那题,qi恒定为5,所以也是需要排序的。

ac代码:

#include <stdio.h>

#include <string.h>

#include <algorithm>

using namespace std;

struct node

{

int p,q,v;

} a[555];

int cmp(node x,node y)//按q-p排序,保证差额最小为最优

{

return x.q-x.p<y.q-y.p;

}

int main()

{

int n,m,i,j;

int dp[5555];

while(~scanf("%d%d",&n,&m))

{

for(i = 0; i<n; i++)

scanf("%d%d%d",&a[i].p,&a[i].q,&a[i].v);

memset(dp,0,sizeof(dp));

sort(a,a+n,cmp);

for(i = 0; i<n; i++)

{

for(j = m; j>=a[i].q; j--)//剩余的钱大于q才能买

{

dp[j] = max(dp[j],dp[j-a[i].p]+a[i].v);//这里的j-a[i].p决定了之前的排序方法

}

}

printf("%d\n",dp[m]);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: