HDU 3466——Proud Merchants【01揹包 + 排序消除後效性】

題目傳送門

與順序有關的01揹包,先按q-p排序再來處理,難想容易敲。


Problem Description

Recently, iSea went to an ancient country. For such a long time, it was the most wealthy and powerful kingdom in the world. As a result, the people in this country are still very proud even if their nation hasn’t been so wealthy any more.
The merchants were the most typical, each of them only sold exactly one item, the price was Pi, but they would refuse to make a trade with you if your money were less than Qi, and iSea evaluated every item a value Vi.
If he had M units of money, what’s the maximum value iSea could get?


Input

There are several test cases in the input.

Each test case begin with two integers N, M (1 ≤ N ≤ 500, 1 ≤ M ≤ 5000), indicating the items’ number and the initial money.
Then N lines follow, each line contains three numbers Pi, Qi and Vi (1 ≤ Pi ≤ Qi ≤ 100, 1 ≤ Vi ≤ 1000), their meaning is in the description.

The input terminates by end of file marker.


Output

For each test case, output one integer, indicating maximum value iSea could get.


Sample Input

2 10
10 15 10
5 10 5
3 10
5 10 5
3 5 6
2 7 3


Sample Output

5
11


題意:

你有m塊錢,有n件商品,每件商品有它的價格p 要買這件商品至少擁有的錢數q和價值w,問能獲得的最大價值是多少


分析:

  • 經典的01揹包
  • 商品如果沒有屬性q的話就是一個單純的01揹包,正是因爲該屬性,如果再像01揹包那樣求解的話就有了後效性,因爲很可能存在這種情況:先買物品1就買不了物品2,但是如果先買物品2就可以繼續買物品1.
  • 下面我們來找一下出現這種情況的條件是什麼:假設現在又兩件物品1和2,你手中有k塊錢,而且如果先買1的話能買2,但是先買2的話不能買1,則有:
    p1 + q2 ≤ k < p2 + q1
    移項得,
    q1 - p1 > q2 - p2
    好的,如果兩件商品滿足q1 - p1 > q2 - p2,那麼一定存在一個或多個k值滿足 p1 + q2 ≤ k < p2 + q1 ,所以我們在考慮買物品的時候一定要考慮 q減p 的值大的。
    可是如果你按照q-p從大到小排序的話,就又錯了。由於01揹包是倒序過程,所以需要將
    (p-q)升序排序

AC代碼:

#include <iostream>
#include <vector>
#include <utility>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <cstdio>
#include <fstream>
#include <set>
using namespace std;
typedef long long ll;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

const int MAXN = 5000 + 7;
#define INF 0x3f3f3f


ll dp[MAXN];
struct node {
	int p, q, v;
	bool operator < (const node& t)const {
		return (q - p) < (t.q - t.p);
	}
}node[MAXN];
int main() {

	int n, k;
	while (cin >> n >> k) {
		for (int i = 1; i <= n; i++) {
			cin >> node[i].p >> node[i].q >> node[i].v;
		}
		memset(dp, 0, sizeof dp);
		sort(node + 1, node + n + 1);

		for (int i = 1; i <= n; i++) {
			for (int j = k; j >= node[i].q; j--) {
				dp[j] = max(dp[j], dp[j - node[i].p] + node[i].v);
			}
		}
		cout << dp[k] << endl;
	}

	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章