题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3466
n个商人,每个商人有一个物品,物品有价格p、价值v还有一个交易限制q。q的意义是假如你现在拥有的钱数小于q,那么是不允许交易的。
由于拥有了q这个量,使得整个交易过程有了顺序,这显然破坏了dp的无后效性。我们可以考虑如何先确定这个顺序,让我们可以正常使用dp。
贪心选取q小p大的,也就是q-p差值从小到大排序。这样可以大致确定一个选择顺序,不会证。
#include <algorithm> #include <iostream> #include <iomanip> #include <cstring> #include <climits> #include <complex> #include <fstream> #include <cassert> #include <cstdio> #include <bitset> #include <vector> #include <deque> #include <queue> #include <stack> #include <ctime> #include <set> #include <map> #include <cmath> using namespace std; typedef struct Node { int w, q, v; }Node; const int maxn = 5555; int n, m; int dp[maxn]; Node t[maxn]; bool cmp(Node a, Node b) { return a.q - a.w < b.q - b.w; } int main() { // freopen("in", "r", stdin); while(~scanf("%d %d", &n, &m)) { for(int i = 0; i < n; i++) { scanf("%d%d%d", &t[i].w, &t[i].q, &t[i].v); } memset(dp, 0, sizeof(dp)); sort(t, t+n, cmp); for(int i = 0; i < n; i++) { for(int j = m; j >= t[i].q; j--) { dp[j] = max(dp[j], dp[j-t[i].w]+t[i].v); } } printf("%d ", dp[m]); } return 0; }