开启了背包问题的学习,背包问题是什么?是在给定背包容量的情况下,希望能放下价值最高的组合。实际上最开始应该联想到回溯问题,求出所有可能的组合,并且计算价值,并返回最大的价值。这样的算法效率比较低。因此考虑动态规划的算法。
递推公式:dp[j] = max(dp[j - cost[i]] + value[i], dp[j])。dp[j]代表容量为j的背包能最大装多少价值的物品。要理解在一维数组的递推公式下的几点问题:1. 遍历背包时的顺序,2.先遍历背包还是物品? 3. 初始化问题。
1.遍历背包时从后向前遍历的原因。因为这里是一维数组,dp[j] 不断的在覆盖上一个物品遍历之后的结果。我们希望在遍历当前物品的时候,结合之前背包里已经放物品的之后的价值情况,即dp[j],和假如我放物品,dp[j - cost[i]] + value[i] 的价值大小。因此遍历背包的时候必须从后向前遍历。
2.得先遍历物品再遍历背包。 首先如果是先遍历背包容量,那么就意味着每个容量只会去判断装一个物品的最大价值,实际上背包是能放多个物品的。
3.初始化问题。一定都是初始化为0吗?不是的,要考虑给的值是否有负数。不过如果是求最大价值,遇到负数可以直接跳过的。
- 分割等和子集
一开始采用先排序,然后不断向后遍历并累加,判断leftSum是否等于sum/2。如果找到了返回true,没有的话,返回false,只能通过一半的用例。情况[1,2,1,2] 这种案例没法通过。如何将其与动态规划联系到一起?选若干个物品放到一个固定容量的背包中求其最大价值。本质上类似,将价值为本身的数划分到一块,求其总和。背包的容量为多少?整个数组总和的一半。剩下的思路和背包问题一样。