• 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
    
    */
    

      

     
  • 相关阅读:
    LCA模板
    bzoj1660:[Usaco2006 Nov]badhair乱头发节
    不老的传说
    田忌赛马
    最短路径问题
    hdu2421-Deciphering Password-(欧拉筛+唯一分解定理+积性函数+立方求和公式)
    hdu1215-七夕节-(埃氏筛+唯一分解定理)
    迷宫-(bfs)
    区间或和-(位运算)
    海啸-(矩阵前缀和)
  • 原文地址:https://www.cnblogs.com/chengsheng/p/4834928.html
Copyright © 2020-2023  润新知