HDU 5445 Food Problem 解題報告(揹包)

Food Problem

Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 120    Accepted Submission(s): 33


Problem Description
Few days before a game of orienteering, Bell came to a mathematician to solve a big problem. Bell is preparing the dessert for the game. There are several different types of desserts such as small cookies, little grasshoppers and tiny mantises. Every type of dessert may provide different amounts of energy, and they all take up different size of space.

Other than obtaining the desserts, Bell also needs to consider moving them to the game arena. Different trucks may carry different amounts of desserts in size and of course they have different costs. However, you may split a single dessert into several parts and put them on different trucks, then assemble the parts at the game arena. Note that a dessert does not provide any energy if some part of it is missing.

Bell wants to know how much would it cost at least to provide desserts of a total energy ofp (most of the desserts are not bought with money, so we assume obtaining the desserts costs no money, only the cost of transportation should be considered). Unfortunately the mathematician is having trouble with her stomach, so this problem is left to you.
 

Input
The first line of input contains a integer T(T10) representing the number of test cases.

For each test case there are three integers n,m,p on the first line (1n200,1m200,0p50000), representing the number of different desserts, the number of different trucks and the least energy required respectively.

The ith of the n following lines contains three integers ti,ui,vi(1ti100,1ui100,1vi100) indicating that the ith dessert can provide ti energy, takes up space of size ui and that Bell can prepare at most vi of them.

On each of the next m lines, there are also three integers xj,yj,zj(1xj100,1yj100,1zj100) indicating that the jth truck can carry at most size of xj , hiring each one costs yj and that Bell can hire at most zj of them.
 

Output
For every test case output the minimum cost to provide the dessert of enough energy in the game arena if it is possible and its cost is no more than50000. Otherwise, output TAT on the line instead.
 

Sample Input
4 1 1 7 14 2 1 1 2 2 1 1 10 10 10 1 5 7 2 5 3 34 1 4 1 9 4 2 5 3 3 1 3 3 5 3 2 3 4 5 6 7 5 5 3 8 1 1 1 1 2 1 1 1 1
 

Sample Output
4 14 12 TAT
 

Source
 


    解題報告:揹包。首先計算出滿足能量值p的最小空間大小,再由最小空間大小揹包出最少金錢數。

    簡單計算數據,最小空間大小極端情況下可能會是200 * 100 * 100 = 200W,200W揹包肯定會超時的。

    注意Output裏的提示,錢最多給50000,按照50000的大小揹包出錢對應的最大空間,然後求出符合條件的最少的錢即可。

    PS:比賽的時候我和隊友根本沒看到50000的條件……但是我們AC了……這是一個悲傷的故事

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <functional>
#include <cassert>
#include <bitset>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define ff(i, n) for(int i=0,END=(n);i<END;i++)
#define fff(i, n, m) for(int i=(n),END=(m);i<=END;i++)
#define dff(i, n, m) for(int i=(n),END=(m);i>=END;i--)
#define travel(e, u) for(int e=first[u], v=vv[first[u]]; ~e; e=nxt[e])
#define mid ((l+r)/2)
#define bit(n) (1ll<<(n))
#define clr(a, b) memset(a, b, sizeof(a))
#define debug(x) cout << #x << " = " << x << endl;

#define ls (rt << 1)
#define rs (ls | 1)
#define lson l, m, ls
#define rson m + 1, r, rs

void work();

int main() {
    work();
    return 0;
}

/**************************Beautiful GEGE**********************************/

const int maxn = 222;
const int maxv = 5e4 + 5 + maxn;
const int inf = 0x3f3f3f3f;

int n, m, p;
int dp[maxv];

void zero_one_pack(int v, int c, int V) {
    dff(i, V, v) {
        dp[i] = min(dp[i], dp[i - v] + c);
    }
}

void zero_one_pack2(int v, int c, int V) {
    dff(i, V, v) {
        dp[i] = max(dp[i], dp[i - v] + c);
    }
}

void multi_pack(int v, int c, int num, int V, bool flag = true) {
    int k = 1;
    while (num) {
        if (flag)
            zero_one_pack(v * k, c * k, V);
        else
            zero_one_pack2(v * k, c * k, V);
        num -= k;
        k += k;
        if (k > num) k = num;
    }
}

void input() {
    scanf("%d%d%d", &n, &m, &p);

    clr(dp, inf); dp[0] = 0;
    ff (i, n) {
        int v, c, num;
        scanf("%d%d%d", &v, &c, &num);
        multi_pack(v, c, num, p + 100);
    }
    int V = *min_element(dp + p, dp + p + 100);

    clr(dp, 0);
    ff (i, m) {
        int v, c, num;
        scanf("%d%d%d", &v, &c, &num);

        multi_pack(c, v, num, 50000, false);
    }

    int ans = inf;
    dff(i, 50000, 0) if (dp[i] >= V) {
        ans = min(ans, i);
    }
    if (ans == inf) {
        puts("TAT");
    } else {
        printf("%d\n", ans);
    }
}

void work() {
    int T; scanf("%d", &T);
    fff(cas, 1, T) {
        input();
    }
}


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