HDU 3449 Consumer有依赖的01背包
有个购物车,每个车可以购买特定的商品,买商品之前必须花费代价购买对应的购物车,求可以购买的最大的商品价值。
在有依赖的背包问题中,购物车称为"主件",商品为"附件";每次将主件从第转移到,然后做01背包即可。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<cstdlib>
#define inf 0x7fffffff
#define ll long long
#define mem(a, x) memset(a,x,sizeof(a))
typedef std::pair<ll, ll> Pll;
const int N = 60;
using namespace std;
ll gcd(ll p, ll q) { return q == 0 ? p : gcd(q, p % q); }
ll n, w, p[N], dp[N][1 << 17];
vector<Pll> G[N];
inline void init() {
for (int i = 1; i <= n; i++) G[i].clear();
ll m, c, v;
for (int i = 1; i <= n; i++) {
cin >> p[i] >> m;
while (m--) {
cin >> c >> v;
G[i].push_back(Pll(c, v));
}
}
mem(dp, 0);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
while (cin >> n >> w) {
init();
for (int i = 1; i <= n; i++) {
for (int j = 0; j < p[i]; j++) dp[i][j] = -inf;
for (int j = p[i]; j <= w; j++) dp[i][j] = dp[i - 1][j - p[i]];//从第i-1个主件转移
for (auto &x:G[i]) {
ll c = x.first, v = x.second;
for (int j = w; j >= c; j--)
dp[i][j] = max(dp[i][j], dp[i][j - c] + v);
}//01背包
for (int j = 0; j <= w; j++) dp[i][j] = max(dp[i][j], dp[i - 1][j]);//更新
}
cout << dp[n][w] << endl;
}
return 0;
}
浙公网安备 33010602011771号