您的位置:首页 > 其它

POJ 1276 Cash Machine【多重背包DP】

2014-07-24 16:20 447 查看
题目:http://poj.org/problem?id=1276

多重背包问题,为重量与价值相等的特殊情况,转为01背包

将物品拆成2^k[i]之和,如13=1+2+4+6

时间复杂度:<math>O(V*Σlog n[i])

处理 一件 多重背包中物品的过程,其中amount表示物品的数量:

procedure MultiplePack(cost,weight,amount)
if cost*amount>=V
CompletePack(cost,weight)	//单一物件超出最大值则转换成完全背包
return
integer k=1
while k<amount
ZeroOnePack(k*cost,k*weight)	//01背包
amount=amount-k
k=k*2
ZeroOnePack(amount*cost,amount*weight)	//处理剩余数量,01背包。如4=1+2,处理剩余的1


#include<string.h>
#include<stdio.h>
#define max(a,b) ( (a) > (b) ? (a) : (b) )
int dp[100005];
int main()
{
int cash,n,d,i,j,m,k;
while(scanf("%d%d",&cash,&m)!=EOF)
{
memset(dp,0,sizeof(dp));
for(i=0;i<m;i++)
{
scanf("%d%d",&n,&d);
if(n*d>cash)
{
for(j=d;j<=cash;j++)
dp[j] = max ( dp[j],dp[j - d ] +  d );
continue;
}
k=1;
while(k<n)
{
for(j=cash;j>=k*d;j--)
dp[j] = max ( dp[j],dp[ j - k * d ] + k* d);
n-=k;
k<<=1;
}
for(j=cash;j>=n*d;j--)
dp[j]= max (dp[j],dp[ j - n * d ] + n* d );
}
printf("%d\n",dp[cash]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: