您的位置:首页 > 其它

POJ1276 - Cash Machine(多重背包)

2013-10-29 12:22 323 查看
[b]题目大意[/b]

给定一个容量为M的背包以及n种物品,每种物品有一个体积和数量,要求你用这些物品尽量的装满背包

[b]题解[/b]

就是多重背包~~~~用二进制优化了一下,就是把每种物品的数量cnt拆成由几个数组成,1,2,4,~~~cnt-2^K+1,k满足cnt-2^K+1>0的最大整数,体积和价值乘上相应的数就是相应物品的价值和体积,这样用这些物品能够表示1~~cnt所有的情况~~~这就转化成01背包了~~~

[b]代码:[/b]

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define MAXN 100005
int dp[MAXN];
int  value[15],cnt[15];
int cash,n;
void CompletePack(int c,int w)
{
for(int i=c; i<=cash; i++)
dp[i]=max(dp[i],dp[i-c]+w);
}
void ZeroOnePack(int c,int w)
{
for(int i=cash; i>=c; i--)
dp[i]=max(dp[i],dp[i-c]+w);
}
void MultiplePack(int c,int w,int m)
{
if(c*m>=cash)
{
CompletePack(c,w);
return;
}
int k=1;
while(k<m)
{
ZeroOnePack(k*c,k*w);
m-=k;
k*=2;
}
if(m>0) ZeroOnePack(c*m,w*m);
}
int main()
{

while(scanf("%d",&cash)!=EOF)
{
scanf("%d",&n);
for(int i=1; i<=n; i++) scanf("%d%d",&cnt[i],&value[i]);
memset(dp,0,sizeof(dp));
for(int i=1; i<=n; i++)
MultiplePack(value[i],value[i],cnt[i]);
printf("%d\n",dp[cash]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: