若不取或者取不下,那么结果就是
d
p
[
i
−
1
]
[
j
]
dp[i-1][j]
dp[i−1][j]。
若取,就由前面的状态预留出
w
e
i
g
h
t
[
i
]
weight[i]
weight[i] 的体积再加上
i
i
i物品的价值,即
d
p
[
i
−
1
]
[
j
−
w
e
i
g
h
t
[
i
]
]
+
v
a
l
u
e
[
i
]
dp[i-1][j-weight[i]]+value[i]
dp[i−1][j−weight[i]]+value[i]。
可得二维dp方程
:
d
p
[
i
]
[
j
]
=
m
a
x
(
d
p
[
i
−
1
]
[
j
]
,
d
p
[
i
−
1
]
[
j
−
w
e
i
g
h
t
[
i
]
]
+
v
a
l
u
e
[
i
]
)
:dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i])
:dp[i][j]=max(dp[i−1][j],dp[i−1][j−weight[i]]+value[i])
我们先来看二维的dp矩阵,背包价值是{1,2,3,4,5},对应的体积是{5,4,3,2,1};
i/j
0
1
2
3
4
5
6
7
8
9
10
1
0
0
0
0
0
1
1
1
1
1
1
2
0
0
0
0
2
2
2
2
2
3
3
3
0
0
0
3
3
3
3
5
5
5
5
4
0
0
4
4
4
7
7
7
9
9
9
5
0
5
5
9
9
9
12
12
12
12
14
以
d
p
[
4
]
[
j
]
dp[4][j]
dp[4][j] 到
d
p
[
5
]
[
j
]
dp[5][j]
dp[5][j] 为例,此时第5个物品的体积为1,价值为5
比如
d
p
[
5
]
[
10
]
dp[5][10]
dp[5][10] 的状态是由
d
p
[
5
]
[
10
]
=
m
a
x
(
d
p
[
4
]
[
10
]
,
d
p
[
4
]
[
9
]
+
5
)
=
14
dp[5][10]=max(dp[4][10],dp[4][9]+5)=14
dp[5][10]=max(dp[4][10],dp[4][9]+5)=14 递推得到的
也就是说当我们递推到
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]时,对于那些只要求最终最佳答案的情况来说,只需要
i
−
1
i-1
i−1 这行的数据即可,至于上面的
i
−
2
,
i
−
3
,
.
.
.
,
1
i-2,i-3,...,1
i−2,i−3,...,1 都是不需要的数据。
所以我们可以只用一维数组
d
p
[
j
]
dp[j]
dp[j] 来记录数据
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j] 的状态,在更新的过程中不断用新的数据
d
p
[
j
]
(
d
p
[
i
]
[
j
]
)
dp[j](dp[i][j])
dp[j](dp[i][j]) 覆盖掉旧的数据
d
p
[
j
]
(
d
p
[
i
−
1
]
[
j
]
)
dp[j](dp[i-1][j])
dp[j](dp[i−1][j])。
4.为什么
j
j
j维度在01背包是逆序,完全背包是正序呢
我相信会有很多同学对01背包第二维j为什么是倒着递推有疑惑。
假设我们从正序进行,当
i
=
5
i=5
i=5,
j
=
9
j=9
j=9时,那么此时
d
p
[
9
]
dp[9]
dp[9] 的状态是由前面的
d
p
[
8
]
dp[8]
dp[8] 和
d
p
[
9
]
dp[9]
dp[9] 状态递推得到的,那么现在
d
p
[
9
]
dp[9]
dp[9] 此时存贮的是
d
p
[
5
]
[
9
]
dp[5][9]
dp[5][9] 的状态,那么也就不能保证
d
p
[
5
]
[
10
]
dp[5][10]
dp[5][10] 的递推成功(
d
p
[
5
]
[
10
]
dp[5][10]
dp[5][10] 状态应该是由
d
p
[
4
]
[
10
]
dp[4][10]
dp[4][10] 和
d
p
[
4
]
[
9
]
dp[4][9]
dp[4][9] 递推得到的)
那该怎么确保不覆盖
d
p
[
9
]
dp[9]
dp[9]存贮的数据
d
p
[
4
]
[
9
]
dp[4][9]
dp[4][9]呢,那么倒序就起作用了。
假设当
i
=
5
,
j
=
10
i=5,j=10
i=5,j=10 时,
d
p
[
10
]
dp[10]
dp[10]内的数据存贮的是
d
p
[
4
]
[
10
]
dp[4][10]
dp[4][10] 的数据,由于
j
j
j从尾部开始枚举,
d
p
[
10
]
dp[10]
dp[10] 就会由
d
p
[
9
]
dp[9]
dp[9] 和
d
p
[
10
]
dp[10]
dp[10] 递推得到(
d
p
[
9
]
dp[9]
dp[9] 存贮的是
d
p
[
4
]
[
9
]
dp[4][9]
dp[4][9] ,
d
p
[
10
]
dp[10]
dp[10] 存贮的是
d
p
[
4
]
[
10
]
dp[4][10]
dp[4][10]),那么此时
d
p
[
10
]
dp[10]
dp[10] 的值就更新为了
d
p
[
5
]
[
10
]
dp[5][10]
dp[5][10]。