HDU3466 Proud Merchants

一、题目内容

【题目描述】

现在n个物品,每组物品有三个属性,pi,买这种物品你需要花费的钱,vi,该物品的价值。qi,如果你想要买这种物品你所拥有的钱必须大于qi。
问你能用你所有的钱最多能获得多大价值。
(每个物品只能买一次)

【输入格式】

有多组测试数据。
对于每组测试数据开始时有两个书N,M (1 ≤ N ≤ 500, 1 ≤ M ≤ 5000);分别表示物品的编号和你所拥有的钱数。
然后是N行,每行包含三个数字Pi,Qi和Vi(1≤Pi≤Qi≤100,1≤Vi≤1000),它们的含义在描述中。
输入终止于文件结束标记。

【输出格式】

对于每个测试用例,输出一个整数,表示你可以得到的物品的价值总和的最大值。

【输入样例】

2 10

10 15 10

5 10 5

3 10

5 10 5

3 5 6

2 7 3

【输出样例】

2

4

6

【测试网站】

HDU3466

二、题目分析

因为每个物品都有一个限制q,而01背包dp是从前i个物品转移到前i+1个物品,所以必须保证转移时无后效性,即前面i个物品选择的结果不会影响到后面的选择.
在这里体现在前i个物品中会影响的范围为q-p;如果第i+1个物品的q-p > 前i个物品的q-p,则可以保证如果选择第i个物品,那么前面i+1个物品的q的限制条件都能满足。 即 qi+1 在的位置>qi

三、代码示例

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int maxn = 510;
const int INF = 0x3f3f3f3f;

int n,m;
int dp[5005];
struct Node
{
  int p,q,v;
}a[maxn];

bool cmp (Node a, Node b)
{
  return a.q - a.p < b.q - b.p;
}

int main()
{
  while(~scanf("%d%d",&n,&m))
  {
    for(int i = 0; i < n; i++) scanf("%d%d%d",&a[i].p,&a[i].q,&a[i].v);
    sort(a,a+n,cmp);//排序
    memset(dp,0,sizeof(dp));//初始化dp数组
    for(int i = 0; i < n; i++)
       for(int j = m; j >= a[i].q; j--)
            dp[j] = max(dp[j],dp[j-a[i].p] + a[i].v);//无后效性dp
    printf("%d\n",dp[m]);
  }
  return 0;
}

 上一篇
HDU2955 01 背包 Robberies HDU2955 01 背包 Robberies
一、题目内容【题目描述】 Roy想要抢劫银行,每家银行都有一定的金额和被抓到的概率,知道Roy被抓的最大概率P,求Roy在不被抓的情况下,最多抢劫多少钱。 【输入格式】 第一行输入给出T,即案例数。对于每个场景,第一行输入给出浮点数P,Ro
2018-12-17
下一篇 
HDU5890 Eighty seven HDU5890 Eighty seven
一、题目内容【题目描述】 Fib先生是一所小学的数学老师。在下一课中,他计划教孩子们如何加数字。在课前,他将准备N张数字牌。第i张牌上的号码是ai。在课堂上,每回合,他将删除不超过3张卡片,然后让学生选择任意十张卡片,其中数字的总和为87.
2018-12-17
  目录