您的位置:首页 > 其它

POJ 1276 Cash Machine(动态规划、多重背包)

2011-07-10 20:40 489 查看
这道题是典型的多重背包题,就是说给你的物品有一个去的件数的上限,我们常用的解决多重背包问题的方法是:将件数乘以费用超过背包容量的物品可以使用完全背包的方法进行求解;除此之外的物品我们采用二进制的思想,将该物品的件数拆分成二进制上的数后,看成一个物品进行01背包。这样通过这两种方法就可以解决多重背包问题。
下面是我的ac代码参考:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100010
int dp[MAX];
int nk[15],dk[15];

int inline max(int a,int b)
{
if(a>b) return a;
else return b;
}

int multiplyPack(int v,int n)//多重背包
{
int i,j,k,amount;
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
if(dk[i]*nk[i]>=v)//完全背包
{
for(j=dk[i];j<=v;j++)
dp[j]=max(dp[j],dp[j-dk[i]]+dk[i]);
}
else//01背包
{
amount=nk[i];
k=1;
while(k<amount)
{
for(j=v;j>=k*dk[i];j--)
{
dp[j]=max(dp[j],dp[j-k*dk[i]]+k*dk[i]);
}
amount-=k;
k*=2;
}
for(j=v;j>=amount*dk[i];j--)
dp[j]=max(dp[j],dp[j-amount*dk[i]]+amount*dk[i]);
}
}
return dp[v];
}

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