+#揹包问题
问题:
给定 n 种物品和一个揹包, 物品 i 的重量是 wi , 其价值为 vi , 揹包的容量为 C 。揹包问题是如何选择装入揹包的物品, 使得装入揹包中物品的总价值最大? 如果在选择装入揹包的物品时, 对每种物品 i 只有两种选择: 装入揹包或不装入揹包, 即不能将物品 i 装入揹包多次, 也不能只装入物品 i 的一部分, 则称为 0/1 揹包问题。
形式化:
约束条件:
⎧⎩⎨⎪⎪∑i=1nwixi≤Cxi∈{0,1} (1≤i≤n)
求一个向量:
X=(x1,x2,x3...,xn)
使它满足:
max∑i=1nvixi
求解:
朴素方法:
遍历 X=(x1,x2,x3...,xn) 所有可能 时间复杂度 O(2n)
动态规划:
最优子结构:
X′=(x1,x2,x3...,xn−1) 是子问题:
⎧⎩⎨⎪⎪⎪⎪∑i=1n−1wixi≤C−wnxnxi∈{0,1} (1≤i≤n−1) 的最优解
证明(反证法):
假设: X′=(x1,x2,x3...,xn−1) 不是子问题的最优解
Y=(y1,y2,y3...,yn−1) 是子问题的最优解
则:
∑i=1n−1viyi≥∑i=1n−1vixi
进而得到:
∑i=1n−1viyi+vnxn≥∑i=1n−1vixi+vnxn
得出 X=(x1,x2,x3...,xn) 不是原问题的最优解, X=(y1,y2,y3...,xn) 才是。
与题设矛盾。构造最优解:
如何通过子问题构造最优解?
假如我们有问题:
⎧⎩⎨⎪⎪∑i=1nwixi≤Cxi∈{0,1} (1≤i≤n)
的最优解 X=(x1,x2,x3...,xn)它的子问题是:
1.如果 xn=0 :
⎧⎩⎨⎪⎪⎪⎪∑i=1n−1wixi≤Cxi∈{0,1} (1≤i≤n−1)
2.如果 xn=1 :
⎧⎩⎨⎪⎪⎪⎪∑i=1n−1wixi≤C−wnxi∈{0,1} (1≤i≤n−1)
状态转移方程求解:
设 dp[n,C] 是问题最优解
则:
dp[n,C]={dp[n−1,C] (xn=0)dp[n−1,C−wn]+vn (xn=1)