hdu3466(01背包,贪心)

题意:给你一些钱 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]);
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值