01背包
N件物品和一个容量为V的背包,放入第i件物品所占的空间为Ci,得到的价值是Wi,求解将哪些物品装入背包可使价值总和最大。
特点:每件物品只有一件,可选择放或不放。
状态转移方程
F[i,v]=max{F[i-1,v],F[i-1,v-Ci]+Wi}
F[i,v]表示将前i件物品恰放入一个容量为v的背包可获得的最大价值
“将前i件物品放入容量为v的背包中”这个子问题,只考虑第i件物品放或不放,就可以转化成一个只和前i-1件物品相关的问题
情况1 不放第i件物品
前i-1件物品放入容量为v的背包中,价值为F[i-1,v]
情况2 放第i件物品
前i-1件物品放入剩下的容量为v-Ci的背包中,此时能获得的最大价值为F[i-1,v-Ci]再加上通过放入第i件物品获得的价值Wi
空间复杂度
为了保证计算F[v]时F[v-Ci]保存的是状态F[i-1,v-Ci]的值,要求在每次主循环中以V→v…0的递减顺序计算F[v]
伪代码
F[0...v]←0
for i ←1 to N
for v ←V to Ci
F[v] ←max{F[v],F[v-Ci]+Wi}
背包问题初始化的细节问题
1 恰好装满背包
初始化 F[0]=0 其他F[1…v]均设为负无穷
2 没有要求必须把背包装满,只希望价值最大
初始化应该将F[0…v]全部设为0
完全背包问题
有N种物品和一个容量为V 的背包,每种物品都有无限件可用。放入第i种 物品的费用是Ci,价值是Wi。求解:将哪些物品装入背包,可使这些物品的耗 费的费用总和不超过背包容量,且价值总和最大。
从每件物品的角度考虑:取0件、取1件、取2件……直至取⌊V /Ci⌋件等许多种。
状态转移方程
F[i,v] = max{F[i−1,v−kCi] + kWi |0 ≤ kCi ≤ v}
优化减小其时间复杂度
若两件物品i、j满 足Ci ≤ Cj且Wi ≥ Wj,则将可以将物品j直接去掉,不用考虑。
比较不错的一种方法是:首先将费用大于V 的物品去掉,然后使 用类似计数排序的做法,计算出费用相同的物品中价值最高的是哪个,可 以O(V + N)地完成这个优化。
续使用一维数组伪代码
F[0…v]←0
for i← 1 to N
for v←Ci to V
F[v]←max{F[v],F[v-Ci]+Wi}
等价于
F[i,v]=max{F[i-1,v],F[i,v-Ci]+Wi}
在考虑“加选一件第i种物品”这种策略时,正需要一个可能已选入第i种物品的子结果F[i,v-Ci],必须使用v的递增的顺序循环
未完待续