背包问题

此文系阅读《背包问题九讲》之后的笔记 ,在此先此文作者表示敬意

简单01背包问题

考虑第i件物品放还是不放, 递推公式为:

f[i][v] = max{f[i-1][v], f[i-1][v-cost[i]] + weight[i]}

 

递推第i件物品时,必须知道i-1时的结果,所以用一维数组实现时,for循环倒退

#define N
#define V
int cost[N], weight[N];

for (i = 1; i <= N; ++i) {
   
for (v = V; v >= cost[i]; --v) 

      f[v] = max{f[v], f[v-cost[i]] + wight[i]};

 根据有么有要求背包刚好填满:

yes:初始化时除f[0] = 0;其他都初始化为无穷小

no: 都初始化为0


完全背包问题

每个物品可以放多次。

ExpandedBlockStart.giffor (i = 1; i <= N; ++i) {
   
for (v = 0; v <= V; ++v) 

      f[v] = max{f[v], f[v-cost[i]] + wight[i]};


for (i = 1; i <= N; ++i) {
   
for (v = 0; v <= V; ++v) 

      f[v] 
= max{f[v], f[v-cost[i]] + wight[i]};

多重背包问题

每个物品有上界n[i], 和完全背包类似。

n[i]可以分为1、2、4、…… 2*k-1、n[i]-2^(k-1)系数乘以cost[i]。

原问题转化为了复杂度为O(V*Σlog n[i])的01背包问题 ,分成0..2^k-1和2^k..n[i]两段

for (i = 1; i < N; ++i) {
   
if (cost[i] * amount[i] >= V) {
      CompletePack(cost[i], weight[i]);
      
return;
   }
   
int k = 1;
   
while (k < amount[i]) {
      ZeroOnePack(k
*cost[i], k*weight[i]);
      amount[i] 
= amount[i] - k;
      k 
= k*2;
   }
   ZeroOnePack(amount[i]
*cost[i], amount[i]*weight[i]);

}

 混合三种背包问题

前面三种背包的集合,

for i=1..N
    
if 第i件物品属于01背包
        ZeroOnePack(c[i],w[i])
    
else if 第i件物品属于完全背包
        CompletePack(c[i],w[i])
    
else if 第i件物品属于多重背包
        MultiplePack(c[i],w[i],n[i])

 

 

 

 

转载于:https://www.cnblogs.com/wsns/articles/1406428.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值