s1049
All checks were successful
ci/woodpecker/push/test Pipeline was successful

This commit is contained in:
Sainnhe Park 2023-02-09 15:52:59 +08:00
parent 43be72324d
commit 8551696b52
5 changed files with 89 additions and 1 deletions

View File

@ -0,0 +1,14 @@
#ifndef S1049_LAST_STONE_WEIGHT_II_HPP
#define S1049_LAST_STONE_WEIGHT_II_HPP
#include <algorithm>
#include <vector>
using namespace std;
class S1049 {
public:
int lastStoneWeightII(vector<int>& stones);
};
#endif

View File

@ -7,7 +7,7 @@
1. 确定 `dp[i]` 是什么
2. 确定递推公式
3. `dp` 数组如何初始化
4. 确定遍历顺序(从前向后还是从后向前)
4. 确定遍历顺序(从前向后还是从后向前)和范围
5. 推几个来验证
技巧:

View File

@ -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 开始。

View File

@ -0,0 +1,15 @@
#include "s1049_last_stone_weight_ii.hpp"
int S1049::lastStoneWeightII(vector<int>& stones) {
int total{0};
int len = stones.size();
vector<int> dp(30 * 1000 / 2 + 1, 0);
for (int i{0}; i < len; ++i) total += stones[i];
int limit = total >> 1;
for (int i{0}; i < len; ++i) {
for (int j = limit; j >= stones[i]; --j) {
dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);
}
}
return total - dp[limit] * 2;
}

View File

@ -0,0 +1,24 @@
#include "s1049_last_stone_weight_ii.hpp"
#include <gtest/gtest.h>
TEST(Problem1049, Case1) {
vector<int> stones{2, 7, 4, 1, 8, 1};
int expected{1};
S1049 solution;
EXPECT_EQ(solution.lastStoneWeightII(stones), expected);
}
TEST(Problem1049, Case2) {
vector<int> stones{31, 26, 33, 21, 40};
int expected{5};
S1049 solution;
EXPECT_EQ(solution.lastStoneWeightII(stones), expected);
}
TEST(Problem1049, Case3) {
vector<int> stones{57, 32, 40, 27, 35, 61};
int expected{4};
S1049 solution;
EXPECT_EQ(solution.lastStoneWeightII(stones), expected);
}