Food Problem

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

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
 
Source
 
 
题目大意:T组测试数据。给你n种食物,m种货车,p表示询问运送不少于p能量值的食物最少需要的运费。然后给你n种食物的能量值energy,食物的体积大小size,这种食物的份数amount。然后m种货车,每种货车能运送的体积siz,运费cost,这种车有多少辆number。如果运费多于5W或者不能达到运送的要求,输出TAT。
 
解题思路:两次多重背包。第一次定义dp[j]=min(dp[j],dp[j-k*energy]+size*k)表示能量为j时需要的最少空间。第二次定义dp[j]=max(dp[j],dp[j-k*size]+k*number)。表示运费为j时最大运输量。对于能量的背包最大容量,我们取所有食物的能量和与50000的最小值。对于花费的背包最大容量,我们取所有货车的花费和与50000的最小值。最后需要从p到取的能量的最小值中找一个最小的值作为阀值,找出最小不小于阀值的花费。
 
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
struct Cake{
int energy,siz,amont;
}cakes[220];
struct Truck{
int siz,cost,num;
}trucks[220];
int dp1[55000],dp2[55000];
void ZeroOnePack(int cost,int weight,int V,int *dp,int typ){
if(typ==1)
for(int i=V;i>=cost;i--){
dp[i]=min(dp[i],dp[i-cost]+weight);
}
else
for(int i=V;i>=cost;i--){
dp[i]=max(dp[i],dp[i-cost]+weight);
}
}
void CompletePack(int cost,int weight,int V,int *dp,int typ){
if(typ==1)
for(int i=cost;i<=V;i++){
dp[i]=min(dp[i],dp[i-cost]+weight);
}
else
for(int i=cost;i<=V;i++){
dp[i]=max(dp[i],dp[i-cost]+weight);
}
}
void MultiplePack(int cost,int weight,int amount,int V,int *d,int typ){
if(cost*amount>=V){
CompletePack(cost,weight,V,d,typ);
return ;
}
int k=1;
while(amount>k){
ZeroOnePack(cost*k,weight*k,V,d,typ);
amount-=k;
k*=2;
}
ZeroOnePack(cost*amount,weight*amount,V,d,typ);
}
int main(){
int T,n,m,p;
scanf("%d",&T);
while(T--){
memset(dp1,INF,sizeof(dp1));
memset(dp2,0,sizeof(dp2));
dp1[0]=0;
int vv=0,cc=0;
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&cakes[i].energy,&cakes[i].siz,&cakes[i].amont);
vv+=cakes[i].energy*cakes[i].amont;
}
for(int i=1;i<=m;i++){
scanf("%d%d%d",&trucks[i].siz,&trucks[i].cost,&trucks[i].num);
cc+=trucks[i].cost*trucks[i].num;
}
vv=min(50000,vv);
for(int i=1;i<=n;i++){
MultiplePack(cakes[i].energy,cakes[i].siz,cakes[i].amont,vv,dp1,1);
}
cc=min(cc,50000);
for(int i=1;i<=m;i++){
MultiplePack(trucks[i].cost,trucks[i].siz,trucks[i].num,cc,dp2,2);
}
int pos=0;
int tmp=INF;
for(int i=p;i<=vv;i++){
tmp=min(dp1[i],tmp);
}
for(int i=1;i<=cc;i++){
if(dp2[i]>=tmp){
pos=i; break;
}
}
if(pos==0){
printf("TAT\n");
}else{
printf("%d\n",pos);
}
}
return 0;
} /*
555
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 */

  

 

HDU 5445——Food Problem——————【多重背包】的更多相关文章

  1. hdu 5445 Food Problem 多重背包

    Food Problem Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5 ...

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

    题目链接: Hdu  5445 Food Problem 题目描述: 有n种甜点,每种都有三个属性(能量,空间,数目),有m辆卡车,每种都有是三个属性(空间,花费,数目).问至少运输p能量的甜点,花费 ...

  3. HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化)

    HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化) 题意分析 先把每种硬币按照二进制拆分好,然后做01背包即可.需要注意的是本题只需要求解可以凑出几种金钱的价格,而不需要输出种数 ...

  4. HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化)

    HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化) 题意分析 给出一系列的石头的数量,然后问石头能否被平分成为价值相等的2份.首先可以确定的是如果石头的价值总和为奇数的话,那 ...

  5. HDU 5445 Food Problem(多重背包+二进制优化)

    http://acm.hdu.edu.cn/showproblem.php?pid=5445 题意:现在你要为运动会提供食物,总共需要提供P能量的食物,现在有n种食物,每种食物能提供 t 能量,体积为 ...

  6. hdu 2844 Coins (多重背包)

    题意是给你几个数,再给你这几个数的可以用的个数,然后随机找几个数来累加, 让我算可以累加得到的数的种数! 解题思路:先将背包初始化为-1,再用多重背包计算,最后检索,若bb[i]==i,则说明i这个数 ...

  7. 题解报告:hdu 1059 Dividing(多重背包、多重部分和问题)

    Problem Description Marsha and Bill own a collection of marbles. They want to split the collection a ...

  8. hdu 1059 Dividing bitset 多重背包

    bitset做法 #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a ...

  9. HDU 2844 Coins(多重背包)

    点我看题目 题意 :Whuacmers有n种硬币,分别是面值为A1,A2,.....,An,每一种面值的硬币的数量分别是C1,C2,......,Cn,Whuacmers想买钱包,但是想给人家刚好的钱 ...

随机推荐

  1. SciTE for Ruby的配置

    转自:http://my.oschina.net/xsinger/blog/14229?catalog=71266 下载下面这个文件:http://scintilla.sourceforge.net/ ...

  2. Python-socket发送文件并解决粘包问题

    服务器端要先根据客户端要下载的文件进行判断是否存在,还要根据文件大小来进行传送,最后还要比对文件的md5值来判断传送的文件是否正确,通过判断剩余字节来解决粘包问题 服务器端 # -*- coding: ...

  3. SQL中top使用方法

    转自:https://www.cnblogs.com/wang7/archive/2012/07/09/2582891.html 1. 在编写程序中,我们可能遇到诸如查询最热门的5篇文章或返回满足条件 ...

  4. 在vue项目中使用md5加密

    MD5:信息-摘要算法,是让大容量信息在用数字签名软件签署私人密匙前被"压缩"成一种保密的格式 一般我们把登录和注册信息的密码进行加密 1.安装模块 cnpm install js ...

  5. 在重命名SqlServer数据库时,报5030错误的解决办法

    数据库不能重名名5030的错误,其实很简单原因就是有应用程序正在占用这个连接,使用这样一行命令就可以查询出正在占用的连接 use master select spid from master.dbo. ...

  6. 并行fp-growth图解(mahout)

    FP-growth Apriori算法的一个主要瓶颈在于,为了获得较长的频繁模式,需要生成大量的候选短频繁模式.FP-Growth算法是针对这个瓶颈提出来的全新的一种算法模式.目前,在数据挖掘领域,A ...

  7. macos下清除dnscache

    sudo killall -HUP mDNSResponder 参见链接

  8. Entity Framework Code-First(12):Configure One-to-Many

    Configure One-to-Many Relationship: Here, we will learn how to configure One-to-Many relationship be ...

  9. C# 中out 参数 和 ref参数的区别

    C#中共有4种参数类型,分别是 传值(by value), 传址 (by reference), 输出参数 (by output), 数组参数 (by array) by value => 传值 ...

  10. Linux进程KILL不掉的原因

    做过Linux开发的人通常遇到过一个进程不能kill掉的情况,即使使用的是kill -9方式,而一般的教课书都只说kill -9能杀死任何进程,遇到这种情况时就会感觉到很矛盾,其它这也是正常的,通常有 ...