HDU3466

来源:互联网 发布:编程教育 编辑:程序博客网 时间:2024/06/04 18:42

Proud Merchants

问题描述 :

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?

输入:

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.

输出:

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.

样例输入:

2 1010 15 105 10 53 105 10 53 5 62 7 3

样例输出:

511

每件物品有一个限制,只有当你当前现金大于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,所以也是需要排序的。

view source
001#include <algorithm>
002#include <iostream>
003#include <fstream>
004#include <sstream>
005#include <iomanip>
006 
007#include <map>
008#include <set>
009#include <list>
010#include <stack>
011#include <queue>
012#include <deque>
013#include <vector>
014#include <string>
015#include <bitset>
016#include <memory>
017#include <complex>
018#include <numeric>
019 
020#include <stdio.h>
021#include <stdlib.h>
022#include <string.h>
023#include <math.h>
024#include <time.h>
025#include <ctype.h>
026#include <locale.h>
027 
028using namespace std;
029 
030#pragma pack(4)
031 
032const double  eps = 1e-8;
033const double   pi = acos(-1.0);
034const int     inf = 0x7f7f7f7f;
035 
036#define loop(a,n)                            \
037    for(int i=0;n>i;i++)                     \
038        cout<<a[i]<<(i!=n-1?' ':'\n')
039#define loop2(a,n,m)                         \
040    for(int i=0;n>i;i++)                     \
041        for(int j=0;m>j;j++)                 \
042            cout<<a[i][j]<<(j!=m-1?' ':'\n')
043 
044#define   at(a,i) ((a)&(1<<(i)))
045#define   nt(a,i) ((a)^(1<<(i)))
046#define set1(a,i) ((a)|(1<<(i)))
047#define set0(a,i) ((a)&(~(1<<(i))))
048 
049#define cmp(a,b) (fabs((a)-(b))<eps?0:(((a)-(b))>eps?+1:-1))
050 
051#define lmax(a,b) ((a)>(b)?(a):(b))
052#define lmin(a,b) ((a)<(b)?(a):(b))
053#define fmax(a,b) (cmp(a,b)>0?(a):(b))
054#define fmin(a,b) (cmp(a,b)<0?(a):(b))
055 
056const int MAXV = 5002;
057 
058struct node
059{
060    int p,q,v;
061    bool operator < (node argu) const
062    {
063        return q-p>argu.q-argu.p;
064    }
065}a[502];
066 
067int n,m,dp[MAXV];
068 
069int main()
070{
071    #ifndef ONLINE_JUDGE
072    freopen("Proud Merchants.txt","r",stdin);
073    #else
074    #endif
075 
076    while(scanf("%d %d",&n,&m)!=EOF)
077    {
078        for(int i=0;n>i;i++)
079        {
080            scanf("%d %d %d",&a[i].p,&a[i].q,&a[i].v);
081        }
082        sort(a,a+n);
083        memset(dp,-1,sizeof(dp)); dp[m]=0;
084        int ans=0;
085        for(int i=0;n>i;i++)
086        {
087            for(int j=max(0,a[i].q-a[i].p);m>=j+a[i].p;j++)
088            {
089                if(dp[j+a[i].p]!=-1)
090                {
091                    dp[j]=max(dp[j],dp[j+a[i].p]+a[i].v);
092                    ans=max(ans,dp[j]);
093                }
094            }
095        }
096        printf("%d\n",ans);
097    }
098 
099    return 0;
100}
0 0