关于动态规划背包问题的总结
做了LeetCode背包几道题吧,有些感觉了,故来总结一波。本文只针对01背包和完全背包,对于考研复试够用了。其他背包有待补充.......
如何区分01背包和完全背包?
每种物品只能取一次(或nums数组中的每个数字只能用一次)为01背包。每种物品有无数个(或nums数组中的每个数字可用多次)为完全背包。
背包问题的遍历顺序(针对滚动数组一维dp)?
先遍历物品后遍历背包容量 or 先遍历背包容量后遍历物品?
1. 针对01背包。先遍历物品后遍历背包容量且遍历背包容量时倒序遍历。解释:数组中元素不可重复使用。
2.针对完全背包。先遍历物品后遍历背包容量且遍历背包容量时正序遍历。解释:数组中元素可以重复使用。
3.针对组合个数求和问题。先遍历物品后遍历背包容量。 解释:组合不考虑元素先后顺序问题。
4.针对排列个数求和问题。先遍历背包容量后遍历物品。 解释:排列问题考虑元素先后顺序。
小结:
01背包和完全背包的区别在于内层循环是倒序还是正序。而组合个数和排列个数一般会出现在完全背包中。
递推公式及初始化
1. 最大(小)值(如01背包、完全背包问题)
dp[j] = max(dp[j], dp[j-weight[i]]+value[i]),dp数组一般初始化为0(非负数),若为负数就要初始化为负无穷。若求最小值,数组初始化为正无穷
上面这个公式并不是一成不变的。比如涉及数组数字时,weight和value可能就为nums[i],涉及字符串value[i]可能等于1,表示的字符串本身。
2. 组合排列问题
dp[i] += dp[i-num],dp[0]一般初始化为1
上面这个要注意是否会超int之类的小细节
相关题目及分类
01背包:
ACwing 01背包
LeetCode 416. 分割等和子集
LeetCode1049. 最后一块石头的重量 II
LeetCode 474.一和零
LeetCode 494. 目标和——组合
完全背包:
ACwing 完全背包
LeetCode 518. 零钱兑换 II——组合
LeetCode 377. 组合总和 Ⅳ——排列