01背包问题:一维dp数组(滚动数组)
参考:动态规划:关于01背包问题,你该了解这些!(滚动数组)
笔记:
- 为何能用一维数组对二维数组进行优化?上一层可以重复利用,直接拷贝到当前层
- 一位数组时,遍历背包的顺序为何是j--?也就是倒序遍历,倒叙遍历是为了保证物品i只被放入一次!
- 为何正序遍历会导致物品被放入多次?正序遍历,也就是j++,举例子即j=1,2,3,4.......也就是dp[1] dp[2] dp[3]这些状态。。。
- 接3
举一个例子:物品0的重量weight[0] = 1,价值value[0] = 15
如果正序遍历
dp[1] = dp[1 - weight[0]] + value[0] = 15
dp[2] = dp[2 - weight[0]] + value[0] = 30==dp[1]+value[0]== dp[1 - weight[0]] + value[0]+value[0]
此时dp[2]就已经是30了,意味着物品0,被放入了两次,所以不能正序遍历。dp[2]依赖dp[1]的状态,先计算dp[1]的,当再计算dp[2]的时候,又要用到dp[1],所以物品0被算了两次。
- 倒序遍历是为了防止什么?防止物品被放入了两次
- 倒序遍历为何能保证物品只放入一次呢?
- 接6:
倒叙就是先算dp[2]
dp[2] = dp[2 - weight[0]] + value[0] = 15 (dp数组已经都初始化为0)
dp[1] = dp[1 - weight[0]] + value[0] = 15
所以从后往前循环,每次取得状态不会和之前取得状态重合,这样每种物品就只取一次了。
- 二维数组遍历背包的时候为什么不用倒序遍历?
因为对于二维dp,dp[i][j]都是通过上一层即dp[i - 1][j]计算而来,本层的dp[i][j]并不会被覆盖!