hdu 5445 Food Problem 多重背包

Food Problem

Time Limit: 1 Sec

Memory Limit: 256 MB

题目连接

http://acm.hdu.edu.cn/showproblem.php?pid=5445

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 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(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

HINT

题意

给你一些糖,有体积和价值和数量,糖果是可以拆分的

然后给你一些背包,每个背包需要钱,可以装v的体积糖果,然后有k个背包

问你最小多少花费买背包,可以获得p点价值的糖果

题解:

拆分糖果就把背包合在一起就好了,当成体积来做

dp1[p]表示体积是P的最小糖果体积

dp2[s]表示money是s时能够获得的最大体积

需要二进制优化/单调队列优化

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <string>
#include <ctime>
#include <list>
#include <bitset>
typedef unsigned char byte;
#define pb push_back
#define input_fast std::ios::sync_with_stdio(false);std::cin.tie(0)
#define local freopen("in.txt","r",stdin)
#define pi acos(-1)

using namespace std;
const int maxn = 200 + 15;

struct item
{
    int val , size;
};

struct item2
{
    int size , cost;
};

int n , m , p ,sz[maxn],dp1[50000+500],sz2[maxn],dp2[50000+500];
item2  B[maxn][55] ;
item A[maxn][55];

void initiation()
{
    memset( sz , 0 ,sizeof(sz));
    memset( sz2,0,sizeof(sz2));
    scanf("%d%d%d",&n,&m,&p);
    for(int i = 1 ; i <= n ; ++ i)
    {
        int v , sq , number , cot = 0;
        scanf("%d%d%d",&v,&sq,&number);
        for(int j = 1 ; ; j <<= 1)
        {
            if(cot + j > number)
            {
                int dcv = number - cot;
                if(dcv != 0)
                {
                    A[i][sz[i]].val = dcv*v;
                    A[i][sz[i]].size = dcv*sq;
                    sz[i]++;
                }
                break;
            }
            A[i][sz[i]].val = v*j;
            A[i][sz[i]].size = sq*j;
            sz[i]++;
            cot += j;
        }
    }
    for(int i = 1 ; i <= m ; ++ i)
    {
        int v , sq , number , cot = 0;
        scanf("%d%d%d",&v,&sq,&number);
        for(int j = 1 ; ; j <<= 1)
        {
            if(cot + j > number)
            {
                int dcv = number - cot;
                if(dcv != 0)
                {
                    B[i][sz2[i]].size = dcv*v;
                    B[i][sz2[i]].cost = dcv*sq;
                    sz2[i]++;
                }
                break;
            }
            B[i][sz2[i]].size = v*j;
            B[i][sz2[i]].cost = sq*j;
            sz2[i]++;
            cot += j;
        }
    }
}

inline void updata(int & x,int v)
{
    x = min(x , v);
}

inline void updata2(int & x,int v)
{
    x = max(x , v);
}

void solve()
{
    memset(dp1,0x3f,sizeof(dp1));dp1[0] = 0;
    int error = dp1[1];
    for(int i = 1 ; i <= n ; ++ i)
     {
        for(int z = 0 ; z < sz[i] ; ++ z)
         {
            for(int j = p - 1 ; j >= 0 ; -- j)
            {
               if(dp1[j] == error ) continue;
               int newj = j + A[i][z].val;
               int newcost = dp1[j] + A[i][z].size;
               if(newj >= p ) newj=p;
               updata(dp1[newj],newcost);
            }
         }
     }
     if(dp1[p] == error)
     {
         printf("TAT\n");
         return;
     }
     int need = dp1[p];
     memset(dp2,0,sizeof(dp2));
     for(int i = 1 ; i <= m ; ++ i)
     {
        for(int z = 0 ; z < sz2[i] ; ++ z)
        {
            int cost = B[i][z].cost;
            int size = B[i][z].size;
            for(int j = 5e4 ; j >= cost ; -- j) updata2(dp2[j] , dp2[j-cost] + size);
        }
     }
     int ans = -1;
     for(int i = 0 ; i <= 5e4 ; ++ i)
     {
        if(dp2[i] >= need)
        {
            ans = i;
            break;
        }
     }
     if(~ans) printf("%d\n",ans);
     else printf("TAT\n");
}

int main(int argc,char *argv[])
{
    int Case;
    scanf("%d",&Case);
    while(Case--)
    {
        initiation();
        solve();
    }
    return 0;
}
时间: 2024-10-14 17:01:58

hdu 5445 Food Problem 多重背包的相关文章

Hdu 5445 Food Problem (2015长春网络赛 ACM/ICPC Asia Regional Changchun Online)

题目链接: Hdu  5445 Food Problem 题目描述: 有n种甜点,每种都有三个属性(能量,空间,数目),有m辆卡车,每种都有是三个属性(空间,花费,数目).问至少运输p能量的甜点,花费最小是多少? 解题思路: 明显可以看出是多重背包搞两次,但是数据范围太大了,背包要到2*1e6,感觉会TLe.还是呆呆的写了一发,果断超啊!然后滚回去看背包九讲课件了,看到了二进制压缩的时候,感觉可以搞这个题目.试了一下果然AC,原本物品数目是100*100,二进制压缩以后也就是100*log210

BestCoder Round #82 (div.1) 1002 HDU 5677 dp-类似多重背包的思想

链接:戳这里 ztr loves substring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description ztr love reserach substring.Today ,he has n string.Now ztr want to konw,can he take out exactly k palindrome from all s

[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

HDU 2844 Coins【多重背包】

大意: 有n种物品 告诉你每种物品的价值和数量 问你能拼凑出1--m之内的多少个数 分析: 多重背包 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int maxn = 100005; 7 int dp[maxn]; 8 int num[maxn], va[maxn]; 9 int vo[maxn]; 10 int n

HDU 1059 Dividing (多重背包)

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

hdu 2844 coins (多重背包)

#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int a[120],c[120]; int dp[100000+100]; int main() { int n,m; int i,j,k; while(scanf("%d%d",&n,&m

多重背包-动态规划(2)

汶川大地震——HDU 2191 简单的多重背包 时间不多 最近拖拖拉拉 暂时没时间再深入理解动态规划了 把这个改成01背包简单贴一下代码... 埋下了这样的坑 # include<iostream> # include<algorithm> # include<cstring> using namespace std; //n,m,p,h,c int dp[105]; int p[105], h[105], c[105]; int n, m; void mul_bag(

有关货币问题的动态规划题目--有关01背包,完全背包,多重背包

背包dp:参考背包九讲以及给出一些题目 01背包 (先枚举物品,再逆序枚举容量) 给定n件物品和一个容量为V的背包,每件物品的体积是w[i],价值是va[i](1<=i<=n),求在不超过背包的容量的情况下,怎么选择装这些物品使得得到的价值最大? 例如:有5件物品,体积分别是{2,2,6,5,4},价值分别是{6,3,5,4,6} 递归式:F(i,v)=max(F(i-1,v), F(i-1,v-w[i])+va[i]),其中F(i,v)表示把前i种物品恰放入背包容量为v时取得的最大价值 把这

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 sol