心得
题解
- 将问题转化为分两堆,尽可能同,这样两堆作差就最小,转成0 1背包问题,跟拆分整数一致,此题重量和价值都是一样
class Solution {
public:
int lastStoneWeightII(vector<int>& stones) {
vector<int> dp(1501, 0)
int sum = 0
for (int stone : stones) {
sum += stone
}
for (int i = 0
for (int j = sum / 2
dp[j] = max(dp[j], dp[j - stones[i]] + stones[i])
}
}
return sum - dp[sum / 2] - dp[sum / 2]
}
}
心得
题解
- 还是一个转换的问题,选择的时候,有正有负,目标和target,也就是说正的一堆,负的另一堆,即left - right = target, left + right = target,求和消right得left = (target + sum) / 2这样就转化为遍历,背包容量为left的情况
- 但是本题在于并非求价值最大,而是恰好,也就是之前的递推公式max是每次取得最大,这是其实取得就是每次的和,也就是+=
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int target) {
int sum = 0
for (int i = 0
if (abs(target) > sum) return 0
if ((target + sum) % 2 == 1) return 0
int bagSize = (target + sum) / 2
vector<int> dp(bagSize + 1, 0)
dp[0] = 1
for (int i = 0
for (int j = bagSize
dp[j] += dp[j - nums[i]]
}
}
return dp[bagSize]
}
}
心得
题解
- 还是01背包,主要还是取不取的问题,然后取时候有约束使得取最值,这种最值情况就是原01背包递推公式直接套用,但是约束条件扩充为二维,逻辑还是与之前的一致,逆序,对于max类型的初始化同样都是0
class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0))
for (string str : strs) { // 遍历物品
int oneNum = 0, zeroNum = 0
for (char c : str) {
if (c == '0') zeroNum++
else oneNum++
}
for (int i = m
for (int j = n
dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1)
}
}
}
return dp[m][n]
}
}