• HDU 5445——Food Problem——————【多重背包】


    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(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 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(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 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
    ");
            }else{
                printf("%d
    ",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
    
    */
    

      

     
  • 相关阅读:
    Net框架下的XSLT转换技术简介
    ASP.NET单点登录(代码)
    IE直接下载汇总
    获取客户端网卡MAC地址和IP地址的几种方法(一)
    .NET专区用ASP.Net获取客户端网卡的MAC
    C#枚举系统安装的所有打印机
    Div+CSS布局入门教程
    动态加载JS脚本的4种方法
    WebService获取服务端硬件信息和客户端IP,MAC,浏览器信息,所在城市
    股票中的名词解释
  • 原文地址:https://www.cnblogs.com/chengsheng/p/4834928.html
Copyright © 2020-2023  润新知