0-1背包问题练习
题目描述:
编号为a,b,c,d,e的5个物品,体积分别为2,2,6,5,4,价值分别为6,3,5,4,6。现在有一个容量为10的背包,如何往包中装东西,使得包里的物品总价值最大。
这就是0-1背包问题,0、1分别代表是否选在该物品。解决此类问题最常用的方法就是动态规划。
我们用一个数组记录背包容量从1到10的所有最优情况,只要能构造出这个数组,就能求出最优解。
id | capacity | value | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
a | 2 | 6 | 0 | 6 | 6 | 9 | 9 | 12 | 12 | 15 | 15 | 15 |
b | 2 | 3 | 0 | 3 | 3 | 6 | 6 | 9 | 9 | 9 | 10 | 11 |
c | 6 | 5 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 11 |
d | 5 | 4 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 10 |
e | 4 | 6 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
需要说明的是,这张表是从下往上,从右往左填写的。对于e那行的第一列,我们用(e,1)表示,很明显(e,1)=0,(e,2)=0, (e,3)=0, (e, 4)=6 等等等等。
(e,1) = 0,表示当前只有e这一个物品,同时背包容量为1,由于e的体积大于背包容量,所以e放不进去,那么此时背包的最大价值是0。同理(e,4) = 6,表示背包容量为4时,e能放进去了,所以背包价值为6。
(d,1) = 0,表示当前物品有d和e,背包的容量为1,由于容量太小d和e都放不进去,所以背包的价值为0。同理(d,5) = 6,表示当背包容量为5时,d和e只能放一个,因为e的价值高,所以放入e,此时背包的价值为6。(d,9) = 10, 表示当背包容量为9时,d和e都能放进去,此时背包的价值是9。
经过上面的论述,可以总结出以下规律:
假设我们有0,1,2,…,i,…n个物体,用m(i, j)表示现在遍历到第 i 个物体,并且当前背包容量为 j 时背包的价值,
- 如果背包放不下它,那么m(i,j) = m(i-1, j),背包当前的状态和之前一样一样的
- 如果背包能放下它,那么m(i,j) = max{ m(i-1,j), m(i-1, j-c) + v) },放还是不放这是个问题,如果价值变大了,就放。其中c表示物体 i 的体积,v表示 i 的价值。
这个规律,就是传说中的状态转移方程~,有了它我们的程序就好写了。
注:程序没有考虑特殊输入,和非法输入,仅为了验证动态规划的思想。作者纯小白一枚~
总结一下:
理解状态转移方程,就理解了这个类型的问题
- 如果背包放不下它,那么m(i,j) = m(i-1, j),背包当前的状态和之前一样一样的
- 如果背包能放下它,那么m(i,j) = max{ m(i-1,j), m(i-1, j-c) + v) },放还是不放这是个问题,如果价值变大了,就放。其中c表示物体 i 的体积,v表示 i 的价值。
加油哦!!