1049. 最后一块石头的重量 II
class Solution {
// 找到重量最接近的两组石头
// 最小的可能重量 = 石头总和 - 2 * 重量最接近的两组石头中较小的那组
public:
int lastStoneWeightII(vector<int>& stones) {
vector<int> dp(15001, 0);
int sum = std::accumulate(stones.begin(), stones.end(), 0);
int target = sum / 2;
for (int i = 0; i < stones.size(); i++) {
for (int j = target; j >= stones[i]; j--) {
dp[j] = std::max(dp[j], dp[j-stones[i]] + stones[i]);
}
}
return sum - dp[target] * 2;
}
};
494. 目标和
class Solution {
// left - right = target, left + right = sum
// left = (sum + target) / 2
// 求 left 有多少种组合法
public:
int findTargetSumWays(vector<int>& nums, int target) {
int sum = std::accumulate(nums.begin(), nums.end(), 0);
if (std::abs(target) > sum) return 0;
if ((sum + target) % 2 == 1) return 0;
int bag_size = (sum + target) / 2;
vector<int> dp(bag_size + 1, 0); // 最多有多少种组合法
dp[0] = 1;
for (int i = 0; i < nums.size(); i++) {
for (int j = bag_size; j >= nums[i]; j--) {
dp[j] += dp[j-nums[i]];
}
}
return dp[bag_size];
}
};
474. 一和零
class Solution {
// 物品是strs,背包容量是m和n
public:
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0)); // 最大子集长度
for (std::string str : strs) {
int zero_num =0, one_num = 0;
for(char c : str) {
if (c == '0') zero_num++;
else one_num++;
}
for(int i = m; i >= zero_num; i--) {
for (int j = n; j >= one_num; j--) {
dp[i][j] = std::max(dp[i][j], dp[i-zero_num][j-one_num] + 1);
}
}
}
return dp[m][n];
}
};