六、背包问题
(1):概述
背包问题:有n个物品,第i个物品的价值为Vi,重量为Wi,并且均为非负数,背包的容量为W(非负数),现需要考虑如何选择装入背包的物品,使装入背包的物品总价值最大化
设:某一背包纵容量为W17,五种物品如图

)1.部分背包(物品可分隔)
这类问题通常可以通过依次选择单位价值(Vi/Wi)最大的物品进行放入,剩余体积不够时进行切割,可以得到最优结果
依次选择单位价值最大,物品5 + 物品3 = 29,29 + 物品2的一部分
)2.0-1背包(物品不可分割)
放置策略:可以将背包问题的求解过程看作是进行一系列决策的过程,即决定哪些物品应该放入背包(总价值最大化)
1、优先放体积最大(贪心法),超过背包体积则放弃其他物品(W5 + W4 = 30)
2、优先放价值最大(贪心法),超过背包体积则放弃其他物品(V5 + V4 = 30)
3、优先放单位价值最大(贪心法),超过背包体积则放弃其他物品(物品5 + 物品3 = 29)
4、按顺序放置(回溯法),不合适就退出来重新放,直到尝试完背包能够放置的所有方案
(1、2、3 = 19)
(1、2、4 = 20)
······
(*)
5、刻画0-1背包问题的最优解的结构(动态规划法):如果一个问题在最优解包含了物品n,即Xn = 1,那么其余X1、X2、······、Xn-1一定构成子问题1、2、······、n-1在容量W-Wn的最优解。如果这个最优解不包含物品n,即Xn = 0,那么其余X1、X2、······、Xn-1一定构成子问题1、2、······、n-1在容量W的最优解。
递归式:
|-------------|-------------------------------------------|----------------------|---|
| | 执行 | 条件 | |
| | 0 | i==0 或 W==0 | |
| ci, W { | ci-1, W | Wi>W(表示放不下) | } |
| | max{ci-1, W-Wi+Vi}, ci-1, W}(取最大) | i>0 且 W>=Wi(表示可以放) | |
(2):例题(贪心法)



解:思路:
最先:优先装满
最优:体积最满
问题一:
(1):j = 0(j初始赋值)
(2):bj = bj + si(放置物品)
(3):min = temp(重新赋值最小容量min)
(4):bm = bm + si(放置物品)
问题二:
(5):贪心法
(6):贪心法
(7):O(n^2)(包含while循环)
(8):O(n^2)
问题三:
(9)优先装满:1(1,2,4)+1(3,7)+1(5,6)+1(8,9)+1(10) = 5
(10)体积最少:1(1,2,7,10)+1(3,4)+1(5,6)+1(8,9) = 4
(11):否
(3):例题(回溯法)




解:
>问题一:
(1):k = 1(初始值赋值)
(2):cw = cw + wk(重量赋值)
(3):k = k - 1(回溯)
(4):k = k + 1(继续下一个跳转)
>问题二:
(5):物品2,物品3
(6):35
(7):穷举树:2^4-1=15

(8):8(树已画出)
(4):例题(动态规划法)



解:思路:根据递归式映射C代码逻辑
>问题一:
(1):return cij (返回有效数值)
(2):i > 0 && j >= wi (递归式第三种情况条件)
(3):Calculate_Max_Value(v, w, i-1, j-wi) + vi(递归式第三种情况)
(4):cij = temp;
>问题二:
(5):动态规划法
(6):自顶向下(最大值减1的方式,顶部最大,所以是自顶向下,反之为自底向上)
>问题三:
(7):5,6 = 40