HDU 3449 Consumer有依赖的01背包

nn个购物车,每个车可以购买特定的商品,买商品之前必须花费代价购买对应的购物车,求ww可以购买的最大的商品价值。

在有依赖的背包问题中,购物车称为"主件",商品为"附件";每次将主件从第i1i-1转移到ii,然后做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;
}

posted @ 2019-08-20 13:39  Mr.doublerun  阅读(14)  评论(0)    收藏  举报