[hdu5445 Food Problem]多重背包

题意:一堆食物,有价值、空间、数量三种属性,一些卡车,有空间,价格,数量三种属性。求最少的钱(不超过50000)买卡车装下价值大于等于给定价值的食物,食物可以拆开来放

思路:这题的关键是给定的条件:食物可以拆开来放。这个条件使得卡车和食物可以分开考虑,然后通过空间这个属性联系在一起。做两遍多重背包即可。

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#pragma comment(linker, "/STACK:10240000")
#include <bits/stdc++.h>
using namespace std;

#define X                   first
#define Y                   second
#define pb                  push_back
#define mp                  make_pair
#define all(a)              (a).begin(), (a).end()
#define fillchar(a, x)      memset(a, x, sizeof(a))

typedef long long ll;
typedef pair<int, int> pii;

namespace Debug {
void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<" ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
}
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
/* -------------------------------------------------------------------------------- */

int dp[60000];

void zeroPack_min(int V, int v, int w) {
    for (int i = V; i >= v; i --) {
        umin(dp[i], dp[i - v] + w);
    }
}
void zeroPack_max(int V, int v, int w) {
    for (int i = V; i >= v; i --) {
        umax(dp[i], dp[i - v] + w);
    }
}
void MultiPack(int V, int v, int w, int remain, bool id) {
    if (!remain) return;
    int num = 1;
    while (remain) {
        if (!id) zeroPack_min(V, v * num, w * num);
        else zeroPack_max(V, v * num, w * num);
        remain -= num;
        num <<= 1;
        umin(num, remain);
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
    int T, n, m, p, v, w, c;
    cin >> T;
    while (T --) {
        cin >> n >> m >> p;
        fillchar(dp, 0x3f);
        dp[0] = 0;
        for (int i = 0; i < n; i ++) {
            scanf("%d%d%d", &v, &w, &c);
            MultiPack(p + 100, v, w, c, 0);
        }
        int place = 0x3f3f3f3f;
        for (int i = p; i <= p + 100; i ++) umin(place, dp[i]);
        fillchar(dp, 0);
        for (int i = 0; i < m; i ++) {
            scanf("%d%d%d", &w, &v, &c);
            MultiPack(50000, v, w, c, 1);
        }
        int ans = -1;
        for (int i = 0; i <= 50000; i ++) {
            if (dp[i] >= place) {
                ans = i;
                break;
            }
        }
        if (~ans) cout << ans << endl;
        else puts("TAT");
    }
}
posted @ 2015-09-14 22:58  jklongint  阅读(305)  评论(0编辑  收藏  举报