多重背包问题。
题意是给你一个数目的钱,还有一些 不同数量 也不同面额的钞票。问最接近给定 的数目,不能大于。
老样子,转换为 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 long using 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]); } }
POJ 1276 Cash Machine,布布扣,bubuko.com
原文地址:http://blog.csdn.net/dongshimou/article/details/37728541