HDU - 3466

传送门

传送门

题意:有n件物品,你的钱数是m。每件物品最多买一次,且每件物品除了价格p和价值v外,还有限制q,代表你当前至少有钱数q时,商家才愿意把东西卖给你。求使用不多于m的钱最多获得的价值。

题目就容易让人想到01背包,但不同的是,它多了一个条件,导致这道题不满足dp问题的无后效性。那么我们可以考虑先对贪心的决定物品的选择顺序,再利用01背包求解。

首先会想到贪心地优先选择Q值大的物品,反例:

2(n) 6(m)

3(p1) 5(q1)

1(p2) 4(q2)

然后就会想到优先买P值小的物品,因为这样下一步操作有更多的钱,有更好的选择性。还是反例:

2(n) 4(m)

1(p1) 2(q1)

2(p2) 4(q2)

所以我们就会想到优先购买pi-qi最小的物品。假设由于操作顺序的不同,我们能买的物品数量不同。以上面的数据为例,能买一件物品(先买物品一),也可能买两件物品(先买物品二),那么我们有q1+p2 <= m < p1 + q2,移项则有p2-q2<p1-q1,也就是要优先买p-q小的物品。

定义dp[i]表示以钱数i最多能买到的物品价值。对数组排序后就是有选择顺序的01背包问题。a[1]存储pi-qi最小的物品。如果我们写的是当前状态是可以由那些状态转移得到(区别于当前状态可以转移到那些状态),那么第一层循环方向应该是N到1的。

或者说从无后效性的角度考虑,即要求每个子问题的决策不能对后面其他未解决的问题产影响,所以我们应当是从大状态转移到小状态(或者理解为当前状态为前面已经更新过的某个状态的子集),就是后面更新的dp[j] = max(dp[j], dp[j - a[i].p] + a[i].v);中的j-a[i].p的状态应当在前面已经更新过了。所以要优先处理出q-p的值小的

怎么32行那行判断语句不加也能AC不会越界的,是数据默认了q大于p吗...

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #define INF 0x3f3f3f3f
 6 #define MOD 1000000007
 7 using namespace std;
 8 typedef long long LL;
 9
10 const int maxn = 5e2 + 10;
11 const int maxm = 5e3 + 10;
12
13 struct node {
14     int p, q, v;
15 }a[maxn];
16 int dp[maxm];
17 int N, M;
18
19 bool cmp(struct node& A, struct node& B) {
20     return (A.p - A.q) < (B.p - B.q);
21 }
22
23 int main(int argc, const char * argv[]) {
24     while (~scanf("%d%d", &N, &M)) {
25         for (int i = 1; i <= N; i++) {
26             scanf("%d%d%d", &a[i].p, &a[i].q, &a[i].v);
27         }
28         sort(a + 1, a + 1 + N, cmp);
29         memset(dp, 0, sizeof(dp));
30         for (int i = N; i >= 1; i--) {
31             for (int j = M; j >= a[i].q; j--) {
32                 if (j < a[i].p) break;//
33                 dp[j] = max(dp[j], dp[j - a[i].p] + a[i].v);
34             }
35         }
36         printf("%d\n", dp[M]);
37     }
38     return 0;
39 }
时间: 2024-10-20 19:14:06

HDU - 3466的相关文章

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(0-1背包)

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

HDU 3466(01背包变种

http://acm.hdu.edu.cn/showproblem.php?pid=3466 http://www.cnblogs.com/andre0506/archive/2012/09/20/2695841.html 这道题多了一个限制条件Qi,低于Qi时不能购买. 解题思路是看更新量,因为限制条件限制的是更新量. 比如一个物品是5 9,一个物品是5 6,对第一个进行背包的时候只有dp[9],dp[10],…,dp[m],再对第二个进行背包的时候,如果是普通的,应该会借用前面的dp[8],

HDU 3466 Moo Volume

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description Farmer John has received a noise complaint from his neighbor, Farmer Bob, stating that his cows are making too much noise. FJ's N cows (1 <= N <= 10,000) all

hdu 3466 排序01背包

也是好题,带限制的01背包,先排序,再背包 这题因为涉及到q,所以不能直接就01背包了.因为如果一个物品是5 9,一个物品是5 6,对第一个进行背包的时候只有dp[9],dp[10],…,dp[m],再对第二个进行背包的时候,如果是普通的,应该会借用前面的dp[8],dp[7]之类的,但是现在这些值都是0,所以会导致结果出错.于是要想到只有后面要用的值前面都可以得到,那么才不会出错.设A:p1,q1 B:p2,q2,如果先A后B,则至少需要p1+q2的容量,如果先B后A,至少需要p2+q1的容量

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 01背包变形

给出物品数量N和总钱数M 对于N个物品.每一个物品有其花费p[i], 特殊值q[i],价值v[i] q[i] 表示当手中剩余的钱数大于q[i]时,才干够买这个物品 首先对N个物品进行 q-p的排序,表示差额最小的为最优.优先考虑放入这个物品 然后01背包计算 #include "stdio.h" #include "string.h" #include "algorithm" using namespace std; int inf=0x3f3f

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

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