ACM第九周&&第十周背包总结(2021.5.15补)

背包知识理解和总结:

01背包: 每种物品仅有一件,可以选择放与不放。
完全背包: 每种物品无限件。
多重背包: 第i种物品最多有n[i]件可用。
分组背包: 选择本组的某一件,还是一件不选。

★01背包:
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]} ;//f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。
因为该状态f[i][v]只与上一状态有关,所以出现了简化(一维):
f[v]=max{f[v],f[v-c[i]]+w[i]}
还有,一点!逆序!
因为求容量v的状态值时,只与前i-1件物品装入容量小于或等于v的状态有关,与大于v的状态无关。可先更新大容量的状态值。我自己的理解就是,想求现在v容量i件物品最大价值,而需要比较的是上一状态i-1件物品v容量的价值(i不放背包)和i-1件物品v-c[i]容量的价值(i放入背包)。所以不能先把小容量的状态值修改了,否则会影响这一个状态寻找最大值。
链接:
01背包,C题
01背包,D题.

★完全背包:f[i][j]=max{f[i-1][j-k*w[i]]+k*v[i]|0=<k<=V/w[i]}
时间优化:
f[i][j]=max(f[i-1][j], f[i][j–wi]+vi) f[ i ][ v ]//为前 i 种物品恰好放入容量为 v 的背包的最大权值。

理解根据上述状态转移方程可知,假设的是子结果f[ i-1 ][ v-k*w[i] ]中并没有选入第 i 种物品,所以我们需要逆序遍历(像0/1背包一样)来确保该前提;但是现在考虑“加选一件第 i 种物品”这种策略时,正需要一个可能已经选入第 i 种物品的子结果f[ i ][ v-w[i] ],于是当我们顺序遍历时,就刚好达到该要求。这种做法会省去一层循环,即第 i 种物品放入的件数k。
空间优化:

//伪代码
for i = 1..N
   for v = 0..V
     f[v] = max{f[v],f[v-w[i]] + val[ i ] };

理解考虑f[i][j]时,由于是从前往后写,f[j]没被写入,它表示的是f[i-1][j],f[j-w[i]]已被写入,它表示的是f[i][j-w[i]]
那么,一维f[v]=max{f[v],f[v-w[i]]+v[i]}
恰好能表示是二维的f[i][v]=max{f[i-1][v],f[i][v-w[i]]+v[i]}

★多重背包:
有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。(在完全背包的基础上,找到每件物品的最优个数从而就找到了最优解)
理解,因为对于第i种物品有n[i]+1种策略:取0件,取1件……取n[i]件。
f[i][v]//表示前i种物品恰放入一个容量为v的背包的最大权值,则:f[i][v]=max{ f[ i-1 ][ v-k*w[i] ] + k*val[ i ] | 0<= k <= n[ i ]}
具体问题具体分析

★分组背包:
有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。

//伪代码
 for 所有的组k
	   for v=V..0//必须在i循环的外部,这样才能保证每一组最多一个物品
			for 所有的i属于组k
					    f[v]=max{f[v],f[v-c[i]]+w[i]}

具体问题具体分析

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值