背包问题
有n个物品和一个背包,设物品 i 的价值为 vi ,重量为 wi ,可以选择每个物品的一部分放入背包,问怎么放物品可使背包总价值最大。
用贪心法解决
0-1背包问题
有n个物品和一个背包,背包容量是c,物品i的重量是wi,价值是vi,每个物品只有放入背包和不放入两种选择,问在背包容量允许的情况下选择哪些物品可使总价值最大。
★贪心法解决背包问题
★动态规划法解决0-1背包问题
思路:
①动态规划解决0-1背包问题的基本思路是,一个物品一个物品地考虑,这里从第n个开始考虑(从第一个也可以,实质上一样,只是一些数据的下标和代表的意义不一样了,程序也随之不同,会一种很容易理解另一种,这里以从第n个开始考虑为例),每次考虑当前物品是否可以放入,放入带来的价值是否值得
②设m(i,j)为背包容量为j,可选择的物品为i~n时的最优值,放入物品背包容量j会变化。
例如m(1,c)表示,所有物品可选,背包当前容量为c时的最优值,即为问题的解。先考虑第n个物品可选,求出m[n,c],再一个一个考虑下一个物品,直到求出解
③那么有以下递归式,这是理解此问题的核心,把这几个递推式搞清楚动态规划解决0-1背包问题就基本掌握了(w是重量,v是价值)
只考虑第n个物品:
m(n,j)=0 j< Wn (背包装不下物品n)
m(n,j)=Vn j>= Wn (背包能装下物品n)
如果物品i放不进去,考虑i~n其实就是考虑i+1到n:
m(i,j)= m(i+1,j) j<Wi (背包装不下物品 i)
如果可以放进去,那么考虑有物品i和没物品i哪个价值大
m(i,j)=max{m(i+1,j) , m(i+1,j-Wi) +Vi} j>=Wi
程序如下:
以下程序确定哪个物品放入了背包
★回溯法解决0-1背包问题
用回溯法解决0-1背包问题,要构造一颗子集树
也是一个物品一个物品考虑,一层代表一个物品,左子树代表放入当前物品,右子树代表不放入,显然树搜索到叶子节点时候所有物品都考虑过了。如果背包容量足够,则进入左子树,否则不进入,当右子树可能包含最优解才进入,不必进入右子树时我们剪枝右子树,什么情况下剪枝呢?
例如:
程序如下:
★分支限界法解决0-1背包问题
基本思想:
有两种方法: