HDU3466 Proud Merchants(01背包)

题目链接

01背包问题,附加条件是每次购买必须拥有超过q的钱数。

将q-p从小大到排序后直接按照背包搞。

关于q-p从小到大排序的原因,我是这么想的:假设q-p无穷小,那么就变成了一个裸的01背包问题,肯定要先处理小的以免影响后面运算。网上看到一个人的想法也不错:假设两个物品A:p1,q1和B:p2,q2,先买A的话则需要p1+q2的钱,先买B的话需要p2+q1的钱,若p1+q2>p2+q1则q1-p1小于q2-p2.

#include<cstring>
#include<cstdio>
#include<cstring>
#include<cmath>
#include <vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
int dp[5005];
struct node{
    int p, q, v;
}a[1005];
int cmp(node x,node y){
    return x.q-x.p < y.q-y.p;
}

int main(){
    //freopen("a.txt", "r", stdin);
    int n, m;
    while(scanf("%d %d", &n, &m) != EOF){
        memset(dp, 0, sizeof(dp));
        for(int i = 1; i <= n; i++)
            scanf("%d %d %d", &a[i].p, &a[i].q, &a[i].v);
        sort(a+1, a+1+n, cmp);
        for(int i = 1; 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);
            }
        }
        cout << dp[m] << endl;
    }
    return 0;
}
Zhao Li /
Published under (CC) BY-NC-SA in categories 算法  tagged with 01背包  动态规划