刚看完这道题一脸懵逼。。看了别人的解题思路,琢磨了半天,原来这道题也那么水。。仿照01背包2602的模板,做一点小小的改动就行啦。。
不过这道题还是很有价值的,最起码又学到了一个小技巧
题目大意:在一个古老的国家,那里奇葩的商人I只卖一种物品i,该物品的价格为Pi,但是当你手里的钱少于Qi时,商人I是不会把物品i卖给你的,而对你来说这间物品的价值是Vi,如果给你M钱,问你能买到
的物品
的最大价值是多少?
很明显要用01背包解题,但题目又多给出了一个限制条件Qi。。
其实只要找出每个商人所规定的物品差价(即买该物品时最少要有的钱Qi减去该物品的价格Pi),并将所有的商品按照这个差价升序就OK了。排好序就行了吗?的却如此!换个角度想:你手里的钱相当于背包的体积V,当我们做01背包问题时,就是让背包体积从0开始逐渐增加到V,每增加一次就对当前背包能容纳的所有的物品做一次筛选。同理:当把这些物品按照差价排好序后,这个差价就相当于物品的体积!!那么接下来就是01背包的舞台啦~~
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
int p,q,v;
}a[505];
bool cmp(node A,node B){
return A.q-A.p<B.q-B.p;
}//按照物品差价的升序排列
int main(){
int m,n;
int dp[5010];
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);
memset(dp,0,sizeof(dp));
sort(a,a+n,cmp);
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);
for(int k=1;k<=m;k++)
printf("%d ",dp[k]);
printf("\n");
}
printf("%d\n",dp[m]);
}
return 0;
}