多重背包问题。
题意是给你一个数目的钱,另一些 不同数量 也不同面额的钞票。问最接近给定 的数目。不能大于。
老样子。转换为 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 ",dp[m]); } }