Hdu 5445 Food Problem 多重背包

来源:互联网 发布:淘宝是不是搜索引擎 编辑:程序博客网 时间:2024/05/18 02:09

题意:给出n,m,p,分别表示有n种点心,m种卡车,能量p.
然后给出每种点心所能获得的能量,所占卡车的体积,以及每种点心的数量。
再给出每种卡车所能装下的空间,租这种卡车的费用,以及每种卡车的数量。
现要求至少得到能量p所花费的最少费用。
方法:利用多重背包求出得到能量p所占的最小体积。再利用多重背包求出各种花费下所能装下的最大体积。然后找到最小的花费满足其所装下的最大体积大于或等于得到能量p所占的最小体积,问题得解。

#include <iostream>#include <stdio.h>#include <string.h>#include <set>#include <algorithm>#include <math.h>using namespace std;const int INF=0x3f3f3f3f;const int N=205;typedef long long ll;int n,m,p;int denergy[N],dspace[N],dCount[N];int tspace[N],tcost[N],tCount[N];int F[50100];void ZeroOnePack(int C,int W,int V){    for(int v=V;v>=C;v--)        F[v]=min(F[v],F[v-C]+W);}void CompletePack(int C,int W,int V){    for(int v=C;v<=V;v++)        F[v]=min(F[v],F[v-C]+W);}void MultiplePack(int C,int W,int M,int V){    if(C*M>=V){        CompletePack(C,W,V);        return;    }    int k=1;    while(k<M){        ZeroOnePack(k*C,k*W,V);        M=M-k;        k=2*k;    }    ZeroOnePack(C*M,W*M,V);}void ZeroOnePack2(int C,int W,int V){    for(int v=V;v>=C;v--)        F[v]=max(F[v],F[v-C]+W);}void CompletePack2(int C,int W,int V){    for(int v=C;v<=V;v++)        F[v]=max(F[v],F[v-C]+W);}void MultiplePack2(int C,int W,int M,int V){    if(C*M>=V){        CompletePack2(C,W,V);        return;    }    int k=1;    while(k<M){        ZeroOnePack2(k*C,k*W,V);        M=M-k;        k=2*k;    }    ZeroOnePack2(C*M,W*M,V);}int getcost(int space){     int M=50000;    //for(int i=0;i<m;i++)M+=tspace[i]*tCount[i];    memset(F,0,sizeof(F));    for(int i=0;i<m;i++){        MultiplePack2(tcost[i],tspace[i],tCount[i],M);    }    //return F[space];    int ret=INF;    for(int i=0;i<=M;i++)        if(F[i]>=space){            return i;        }    return ret;}int getspace(int energy){       int M=0;    for(int i=0;i<n;i++)M+=denergy[i]*dCount[i];    if(M<energy)return INF;    M=energy+100;    memset(F,0x3f,(M+1)*sizeof(F[0]));    F[0]=0;    for(int i=0;i<n;i++){        MultiplePack(denergy[i],dspace[i],dCount[i],M);    }    //return F[energy];    int ret=INF;    for(int i=energy;i<=M;i++)        ret=min(ret,F[i]);    return ret;}bool solve(){    int space=getspace(p);    if(space==INF)return false;    int cost=getcost(space);    if(cost>50000)return false;    printf("%d\n",cost);    return true;}void work(){    int T;    scanf("%d",&T);    while(T--){        scanf("%d%d%d",&n,&m,&p);        for(int i=0;i<n;i++)            scanf("%d%d%d",&denergy[i],&dspace[i],&dCount[i]);        for(int i=0;i<m;i++)            scanf("%d%d%d",&tspace[i],&tcost[i],&tCount[i]);        if(!solve())            puts("TAT");    }}int main(){    freopen("data.in","r",stdin);    work();    return 0;}
0 0
原创粉丝点击