01背包问题是有N件物品和一个容量为V的背包。第i件物品的体积是v[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。从这个题目中可以看出,01背包的特点就是:每种物品仅有一件,可以选择放或不放。而动态规划法说白了就是填表法。下面不讲原理、不讲概念,以一个例题,用通俗的语言,来说明动态规划法求解01背包问题。
假设有4个物品,它们的价值(v)和重量(w)如下:
物品 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
v | 2 | 4 | 3 | 7 |
w | 2 | 3 | 5 | 5 |
背包总容量为10,现在要从中选择物品装入背包中,要求物品的重量不能超过背包的容量,并且最后放在背包中物品的总价值最大。
首先,我们定义一个二维数组,每一格代表当前最大价值,行j代表背包容量,从0 ~ 10,列i代表物品序号,从0 ~ 1,其中,物品0代表重量为0,价值为零,引入它的原因是方便计算:
i\j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | |||||||||||
1 | |||||||||||
2 | |||||||||||
3 | |||||||||||
4 |
很明显,第一行和第一列都是0,因为第一行代表该物品价值为0,不管背包容量究竟是多少它只能为0,而第一列代表背包容量为0,不管物品有多少,它都装不下:
i\j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | ||||||||||
2 | 0 | ||||||||||
3 | 0 | ||||||||||
4 | 0 |
接着开始从左到右,从上到下的顺序(就是普通的写字顺序)填表,每一个格子在填写时考虑紧挨着它的正上方,正左方,斜左上方的格子,该表格要么填斜上方的值+此行物品的价值,要么填正上方的值或者正左方的值,三者取最大。第一个格子代表将物品1放入容量为1的背包中,由于物品1的重量为2,所以这个格子只能填0:
i\j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | |||||||||
2 | 0 | ||||||||||
3 | 0 | ||||||||||
4 | 0 |
紧接着填第二个格子,由于容量为2的背包足够放入,然后它就需要决定是否放入,如果放入,那么就将该物品的价值与斜左上方的格子里的值相加,这里是0+2=2,如果不放入,那么就直接填入正上方或者正左方格子的值,这里都是0,那么就需要比较最大值,很明显放入时的值最大,那么这个格子填2:
i\j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 2 | ||||||||
2 | 0 | ||||||||||
3 | 0 | ||||||||||
4 | 0 |
紧接着填第三个格子,同样的,要么取斜上方的值+物品价值,要么取正上方或者正左方的值,这里斜上方值+物品价值=正左方值=2,正上方值=0,那么只能填2:
i\j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 2 | 2 | |||||||
2 | 0 | ||||||||||
3 | 0 | ||||||||||
4 | 0 |
按照这个规律将该行填满:
i\j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
2 | 0 | ||||||||||
3 | 0 | ||||||||||
4 | 0 |
接着填下一行第一个,物品2的重量是3,价值是4,那么它只能到第三个格才能插入:
i\j | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
2 | 0 | 0 | 2 | 4 | |||||||
3 | 0 | ||||||||||
4 | 0 |