HDU - 3466
带有条件的01背包应用
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3466、
这个题目的意思是,每个物品有自己的价格Pi但是只有当手里的钱大于等于Qi时才可以购买,问最后在给定的钱的数目下能够买到的最大价值是多少。
这里需要明白一个道理,如果两个物品A和B,虽然购买他们时候得到的价值是相同的,但是购买他们的顺序不同,需要的最小体积(也就是金额)是不同的
- p1+q2
- p2+q1
所以要进行排序,保证在有限的空间内可是实现更大的价值,所以如果
(p1+q2)<(p2+q1)那么肯定要选择先买A再买B的顺序进行商品的购买,反之同理
进行一下转换,就得到(p1-q1)<(p2-q2)所以先进行商品A的购买,所以在代码中我们就要根据这个特性进行一次排序,然后在按照普通的01背包进行操作
注意:其实我感觉01背包进行时,就是一种状态转移的判断,符合的进行转移,不符合的不转移
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
int p,q,r;
int c;
}h[10000];
int dp[10000];
bool cmp(const node a,const node b){
return a.c<b.c;
}
//定义优先级
int main(){
int n,m;
while(~scanf("%d %d",&n,&m)){
for(int i=1;i<=n;i++){
cin>>h[i].p>>h[i].q>>h[i].r;
h[i].c=h[i].q-h[i].p;
}
sort(h+1,h+1+n,cmp);
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++){
for(int j=m;j>=h[i].q;j--){ //这里进行体积判断时是根据第二个进行的,因为只有达到第二个金额才有能力购买
dp[j]=max(dp[j],dp[j-h[i].p]+h[i].r); //操作时有所不同,还是按照本身的体积进行转移,只是能够转移的范围在for循环中与之前不同
}
}
cout<<dp[m]<<endl;
}
return 0;
}