HDU 3591 (多重背包)

来源:互联网 发布:谌洪果 知无知 编辑:程序博客网 时间:2024/06/05 18:15

题意大概:小钱要买价值为t 的物品 ,他有n种不同数量的硬币,求在此次交易所需花费数量最少的硬币数(付款+售货员找回的);


分析:对顾客用多重背包,对售货员用完全背包。
此时背包中的容量为N,价值为1,花费为硬币的价值。
因为输出-1时,也要输出Case ,哇了好多=_=!!!

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define N 20000#define INF 0xfffffffint dp[N],V[105],C[105];void ZeroPack(int v,int w,int m){    for(int i=m;i>=w;i--)        dp[i]=min(dp[i],dp[i-w]+v);}void CompletePack(int v,int w,int m){    for(int i=w;i<=m;i++)        dp[i]=min(dp[i],dp[i-w]+v);}void Multiply(int v,int *w,int n,int m){    for(int i=1;i<=n;i++)    {        if(C[i]*w[i]>m)   //完全背包            CompletePack(v,w[i],m);        else{            int k=1;            while(k<=C[i]){                ZeroPack(k*v,k*w[i],m);                C[i]-=k;                k<<=1;            }            ZeroPack(C[i]*v,C[i]*w[i],m);        }    }}int main(){    int n,t,tt,k=1;    while(scanf("%d%d",&n,&t),n||t){        for(int i=1;i<=n;i++)            scanf("%d",V+i);        for(int i=1;i<=n;i++)            scanf("%d",C+i);        for(int i=1;i<=N;i++)            dp[i]=INF;        dp[0]=0;        Multiply(1,V,n,N);        int co=INF;        for(int i=t;i<=N;i++)            co=min(co,dp[i]+dp[i-t]);//付款+找零        if(co==INF)            co=-1;              printf("Case %d: %d\n",k++,co);    }    return 0;}
0 0
原创粉丝点击