This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
1. 确定 `dp[i]` 是什么
|
||||
2. 确定递推公式
|
||||
3. `dp` 数组如何初始化
|
||||
4. 确定遍历顺序(从前向后还是从后向前)
|
||||
4. 确定遍历顺序(从前向后还是从后向前)和范围
|
||||
5. 推几个来验证
|
||||
|
||||
技巧:
|
||||
|
@@ -124,3 +124,38 @@ void bag_problem_1d() {
|
||||
- 遍历顺序:
|
||||
- `i` 从前往后,范围是 `1 <= i < length`
|
||||
- `j` 从后往前,范围是 `nums[i] <= j <= target`
|
||||
|
||||
本题中可以不初始化第一层,然后 `i` 从 0 开始。
|
||||
|
||||
## [1049. 最后一块石头的重量 II](https://leetcode.cn/problems/last-stone-weight-ii/)
|
||||
|
||||
仔细思考一下每个石头重量的加减方式,你会发现其实最终的重量可以这样表示:
|
||||
|
||||
`final = k0 * w0 + k1 * w1 + k2 * w2 + ...`
|
||||
|
||||
其中 `ki` 为 `+1` 或 `-1`,`wi` 为第 `i` 个石头的重量。
|
||||
|
||||
那么 `ki` 取负的所有石头重量之和我们表示为 `neg`,其它石头重量之和为 `total - neg`。
|
||||
|
||||
我们的目的就是要在 `neg <= total/2` 的前提下,让 `neg` 达到最大。
|
||||
|
||||
这就是一个 01 背包问题。
|
||||
|
||||
- `i` 对应石头下标,每个石头的重量为 `stones[i]`,价值为 `stones[i]`
|
||||
- `j` 对应背包容量,最大为 `total/2`
|
||||
|
||||
我们直接上滚动数组:
|
||||
|
||||
- `dp[j]` 表示从 0 ~ i 中选石头,放进容量为 `j` 的背包,所能达到的最大价值
|
||||
- 迭代公式:
|
||||
- `if (j < stones[i]) dp[j] = dp[j]`
|
||||
- `if (j >= stones[i]) dp[j] = max{dp[j], dp[j - stones[i]] + stones[i]}`
|
||||
- 第二层迭代的范围是 `stones[i] ~ total/2`
|
||||
- 初始化:
|
||||
- `if (j < stones[0]) dp[j] = 0`
|
||||
- `if (j >= stones[0]) dp[j] = stones[0]`
|
||||
- 遍历:
|
||||
- `i` 从 1 到 length - 1
|
||||
- `j` 从 `total/2` 向下取整,遍历到 `stones[i]`
|
||||
|
||||
本题中可以不初始化第一层,然后 `i` 从 0 开始。
|
||||
|
Reference in New Issue
Block a user