背包九讲

背包九讲读书笔记

0-1 背包问题

基本题目套路

N 件物品和一个容量为 V 的背包,放入第 i 件物品消耗的费用是 Ci, 得到的价值是 Wi。 求解将哪些物品装入背包,可使总价值总和最大

基本题目思路
  • 特点:每件物品只有一个,选择: or 不放
  • 子问题:F[i, v]: 前 i 件物品恰好放入容量 v 的背包,可以获得的最大价值
  • 状态转移:F[i, v] = max{F[i-1, v], F[i-1, v-Ci] + Wi}
  • 当前的价值,只和之前的价值有关,因此两个选择下的价值为:
  • 如果 i 不选,价值:前 i-1 件,放入容量 v 的背包(F[i-1, v]
  • 如果 i 选择,价值:前 i-1 件,放入容量(v-Ci)的背包(确保 i 能放下去,得减去 i 占用的容量)+ 放入 i 的价值 Wi
伪代码
1
2
3
4
F[0, 0..V] <- 0
for i <- 1 to N
for v <- Ci to V
F[i, v] <- max{F[i-1, v], F[i-1, v-Ci] + Wi}
优化

时间复杂度:O(VN)
空间复杂度:滚动数组(逆序计算 F[v],才能保证正确的顺序)

1
2
3
4
F[0..V] <- 0
for i <- 1 to N
for v <- V to Ci
F[v] <- max{F[v], F[v-Ci] + Wi}
1
2
3
def ZeroOnePack(F,C,W)
for v <- V to C
F[v] <- max(F[v], F[C-v] + W)
1
2
3
F[0..V] <- 0
for i <- 1 to N
ZeroOnePack(F,Ci,Wi)

完全背包问题

题目基本套路

N 种物品和容量为 V 的背包,每种物品都有无限件可以用,放入第 i 件物品消耗的费用是 Ci, 得到的价值是 Wi。 求解将哪些物品装入背包,可使物品总消耗费用不超过背包容量,且价值总和最大。

基本套路

  • 每种物品无限件,因此每个物品的策略不是:选和不选。而是选几件
  • 状态转移:F[i, v] = max{F[i-1, v-kCi] + kWi | 0 ≤ kCi ≤ v}

简单有效的优化

  • 若两件物品i, j 满足 Ci ≤ CjWi ≥ Wj,则可以将 j 直接去掉,不用考虑 (任何情况下,都可以将价值小费用高的 j 换成物美价廉的 i)
  • 或者 将费用大于 V 的物品去掉

转换为 0-1 背包问题

  • 第 i 种物品最多选:V/Ci 种,把第 i 种物品转化为 V/Ci 件费用及价值不变的物品。 (将一种物品转化为多件只能选 0 或者 1 件的 0-1 背包问题)
  • 二进制:第 i 种物品拆成费用为 Ci2^k,价值为 Wi2^k 的若干件物品。 k 满足 Ci2^k ≤ V 的非负整数。
Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×