hdu 5445 多重背包

Food Problem

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

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 of p (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(T≤10) representing the number of test cases.

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

The i−th of the n following lines contains three integers ti,ui,vi(1≤ti≤100,1≤ui≤100,1≤vi≤100) indicating that the i−th dessert can provide tienergy, 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(1≤xj≤100,1≤yj≤100,1≤zj≤100) indicating that the j−th 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 than 50000. 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

/*
hdu 5445 多重背包

problem:
给一场运动会提供食物,每种食物提供ti能量,占用vi空间,最多可提供ui个,把食物运到指定地点,每种车可以运送ai体积的
食物,消耗bi的金钱,总共有ci个这种车,问给运动会提供至少p的能量,最少需要花多少运费
(每个食物可以拆开来运)

solve:
可以将其分成两个多重背包计算,先计算出运送指定能量的食物最少需要多少的空间,然后在这个空间的基础上计算最少需要
的花费.结果RE,后来发现这个空间可能很大.
而题目中说了50000这个界限,所以直接计算出50000的花费能够达到的最大空间

hhh-2016-08-17 15:13:15
*/
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#define lson  i<<1
#define rson  i<<1|1
#define ll long long
#define key_val ch[ch[root][1]][0]
using namespace std;
const int maxn = 1010;
const int inf = 0x3f3f3f3f;
int dp[51000];
int ta,a,c;

void cal_min(int cost,int val,int num,int m)
{
    if(cost * num >= m)
    {
        for(int i = cost; i <= m; i++)
        {
            dp[i] = min(dp[i],dp[i-cost] + val);
        }
    }
    else
    {
        int k = 1;
        while(k < num)
        {
            for(int i = m; i >= cost*k; i--)
                dp[i] = min(dp[i],dp[i-cost*k]+val*k);
            num -= k;
            k *= 2;
        }
        for(int i = m; i >= cost*num; i--)
            dp[i] = min(dp[i],dp[i-cost*num]+val*num);
    }
}

void cal_max(int cost,int val,int num,int m)
{
    if(cost * num >= m)
    {
        for(int i = cost; i <= m; i++)
        {
            dp[i] = max(dp[i],dp[i-cost] + val);
        }
    }
    else
    {
        int k = 1;
        while(k < num)
        {
            for(int i = m; i >= cost*k; i--)
                dp[i] = max(dp[i],dp[i-cost*k]+val*k);
            num -= k;
            k *= 2;
        }
        for(int i = m; i >= cost*num; i--)
            dp[i] = max(dp[i],dp[i-cost*num]+val*num);
    }
}

int main()
{
//    freopen("in.txt","r",stdin);
    int n,m,cnt;
    int T;
    cin >> T;
    while(T--)
    {
        memset(dp,inf,sizeof(dp));
        dp[0] = 0;
        scanf("%d%d%d",&n,&cnt,&m);
        for(int i = 1; i <= n; i++)
        {
            scanf("%d%d%d",&a,&c,&ta);
            cal_min(a,c,ta,m + 100); //因为每个能量最多100,所以最大界限为m+100
        }
        int minpart = inf;
        for(int i = m; i <= m+100; i++)
        {
            minpart = min(minpart,dp[i]);
        }

//        cout <<"m:" <<m <<"  min:"<<minpart <<endl;
        memset(dp,0,sizeof(dp));
        for(int i = 1; i <= cnt; i++)
        {
            scanf("%d%d%d",&a,&c,&ta);
            cal_max(c,a,ta,50000+100);
        }
        int ans = inf;
        for(int i = 0;i <= 50000;i++){
            if(dp[i] >= minpart)
            {
                ans = i;
                break;
            }
        }
        if(ans == inf)
            printf("TAT\n");
        else
            printf("%d\n",ans);
    }
    return 0;
}

  

时间: 2024-12-12 16:55:26

hdu 5445 多重背包的相关文章

hdu 1171 Big Event in HDU(母函数|多重背包)

http://acm.hdu.edu.cn/showproblem.php?pid=1171 题意:有n种物品,给出每种物品的价值和数目,要将这些物品尽可能的分成相等的两份A和B且A>=B ,输出A,B. 母函数可以过,但感觉最直接的方法应该是多重背包. 母函数的话,也是按总价值的一半求,从一半到小枚举,直到找到系数不为0的就是B. #include <stdio.h> #include <iostream> #include <map> #include <

HDU 1059 多重背包+二进制优化

Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 16909    Accepted Submission(s): 4729 Problem Description Marsha and Bill own a collection of marbles. They want to split the collection

HDU1171--Big Event in HDU(多重背包)

Big Event in HDU   Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1139 Accepted Submission(s): 444 Problem Description Nowadays, we all know that Computer College is the biggest department in HD

hdu 1059 (多重背包) Dividing

这里;http://acm.hdu.edu.cn/showproblem.php?pid=1059 题意是有价值分别为1,2,3,4,5,6的商品各若干个,给出每种商品的数量,问是否能够分成价值相等的两份. 联想到多重背包,稍微用二进制优化一下.(最近身体不适,压力山大啊) 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define inf 70000 5 using namespace s

Big Event in HDU(多重背包套用模板)

http://acm.hdu.edu.cn/showproblem.php?pid=1171 Big Event in HDU Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 28483    Accepted Submission(s): 10027 Problem Description Nowadays, we all know

hdu 2191 多重背包 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活

http://acm.hdu.edu.cn/showproblem.php?pid=2191 New~ 欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院关于2015年杭电ACM暑期集训队的选拔 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17930    Accepted

HDU 2191 多重背包

悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 22865    Accepted Submission(s): 9661 Problem Description 急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市

hdu 2191 多重背包,自己写模板

背景:wa了几次,都是小失误:把i--写成i++之类的,写的时候一定要想到具体用意.还有就是一定要至少写三组测试数据!!!!!!! 学习:模板化写多重背包. #include<cstdio> #include<iostream> #include<cstring> using namespace std; int t,v,n; int c[109],w[109],num[109],F[109]; void zeroonebag(int cost,int weight){

HDU 1171 Big Event in HDU【多重背包】

大意:有n个物品,告诉你每个物品的价值问能否分成价值a.b两份使{a > b  && a + b == 总价值  && a - b尽量小} 分析:多重背包 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int maxn = 55; 7 const int INF = 1000000