您的位置:首页 > 其它

完全背包问题

2008-12-06 11:26 197 查看
背包九讲中解释的非常清楚了,这里不多说。

第一种思路:把第i种物品拆成费用为c[i]*2^k、价值为w[i]*2^k的若干件物品,其中k满足
c[i]*2^k<=V
。这是二进制的思想,因为不管最优策略选几件第i种物品,总可以表示成若干个2^k件物品的和。这样把每种物品拆成O(log V/c[i])件物品,是一个很大的改进。这样就可以把问题转化为01背包了,然后就可以采用01背包的各种求法了:)
void Divide(int *n, int *v)//将一件物品拆分
{
int i, k, t;
t=*n;
for (i=1; i<=t; i++){
for (k=1; cost[i]*pow(2.0, k)<=*v; k++){
cost[++(*n)]=cost[i]*(int)pow(2.0, k);
weight[(*n)]=weight[i]*(int)pow(2.0, k);
}
}
}
第二种思路,将01背包中一维数组解决方案的第二个循环次序倒过来,看伪码:
for i=1....N
for j=0....V
f[j]=max(f[v-cost[i]+weight[i], f[j])
至于为什么参见背包九讲。
int Cbag2(int n, int v)//运用循环颠倒的方法解决完全背包
{
int i, j, sum=0, bound;
for (i=0; i<=v; i++){//初始化
f2[i]=0;
}
for (i=1; i<=n; i++){
for (j=cost[i]; j<=v; j++){
f2[j]=max(f2[j-cost[i]]+weight[i], f2[j]);
}
}
return f2[v];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: