POJ 1276 Cash Machine

来源:互联网 发布:2017洗车软件app 编辑:程序博客网 时间:2024/06/05 17:54

多重背包问题。


题意是给你一个数目的钱,还有一些 不同数量 也不同面额的钞票。问最接近给定 的数目,不能大于。


老样子,转换为 01 背包 和完全背包做。

不过很神奇的是,给多重背包 用二进制思想转换的时候 用 k<<1 。就超时了。用 k*=2 就AC了。好奇怪。


#include<cstdio>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<stack>#include<iostream>#include<list>#include<set>#include<cmath>#define INF 0x7fffffff#define eps 1e-6#define LL long longusing namespace std;int dp[100001];int n,m;int Value[11],Cot[11];void zeroonepack(int cost,int value){    for(int i=m;i>=cost;i--)        dp[i]=max(dp[i],dp[i-cost]+value);}void completepack(int cost,int value){    for(int i=cost;i<=m;i++)        dp[i]=max(dp[i],dp[i-cost]+value);}void multiplepack(int cost,int value,int cot){    int k=1;    while(k<cot)    {        zeroonepack(cost*k,value*k);        cot-=k;        //k<<1; TLE        k*=2;    }    zeroonepack(cost*cot,value*cot);}int main(){    while(scanf("%d%d",&m,&n)!=EOF)    {        for(int i=0;i<n;i++)            scanf("%d%d",&Cot[i],&Value[i]);        memset(dp,0,sizeof(dp));        for(int i=0;i<n;i++)        {            if(Cot[i]==1)                zeroonepack(Value[i],Value[i]);            else if(Value[i]*Cot[i]>=m)                completepack(Value[i],Value[i]);            else                multiplepack(Value[i],Value[i],Cot[i]);        }        printf("%d\n",dp[m]);    }}


0 0
原创粉丝点击