hdu3466(01背包,贪心)

xiaoxiao2021-02-28  46

题意:给你一些钱 m , 共有 n 件物品,每件物品有价格 P,价值 V,还有一个很特别的属性 Q, Q 指你如过想买这件物品你的手中至少有这钱Q 。虽然你只要花费钱P,但你的手中至少有钱Q,如果不足Q,不能买。问给你钱M ,列出N件物品,最多能获得多少价值的东西。 思路:如果没Q的限制条件,这道题就是01背包水题。当我们要购买第i件物品,我们已经花费了j-p[i],我们剩余的钱为m-(j-p[i]),我们要保证m-(j-p[i])>=q[i];变换一下得p[i]<=j<=m+p[i]-q[i],所以我们只需要将物品按(p[i]-q[i])的大小升序排列就可以套用01背包了;

#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <cmath> #include <queue> #include <stack> #define N 100005 #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r #define lc rt<<1 #define rc rt<<1|1 #define INF 0x3f3f3f3f using namespace std; const int maxn = 5005; const int mod = 1000000007; typedef long long ll; int n,m; struct node { int p,q,v; bool operator < (const node& r)const { return q - p < r.q - r.p; } }a[maxn]; int d[maxn]; int main() { //freopen("in","r",stdin); while(~scanf("%d%d",&n,&m)) { for(int i = 1; i <= n; ++i) { scanf("%d%d%d",&a[i].p, &a[i].q,&a[i].v); } sort(a+1,a+n+1); memset(d,0,sizeof(d)); int mx = 0; for(int i = 1; i <= n; ++i) { for(int j = m; j >= a[i].q; --j) { d[j] = max(d[j],d[j - a[i].p] + a[i].v); } } printf("%d\n",d[m]); } }
转载请注明原文地址: https://www.6miu.com/read-81599.html

最新回复(0)