Day43 动态规划 part05
1049.最后一块石头的重量II
我的思路:
提示说和划分两个和相等的子集差不多,猛然想到,这道题不就是划分子集,用sum - 和最大*2
代码就是划分和相同的子集的变形
解答:
class Solution {
public int lastStoneWeightII(int[] stones) {
int sum = Arrays.stream(stones).sum();
int target = sum / 2;
int[] dp = new int[target + 1];
for(int i = 0; i < stones.length; i++) {
for(int j = dp.length - 1; j >= stones[i]; j--) {
dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);
}
}
return sum - dp[target] * 2;
}
}
494.目标和
我的思路:
经历了这些个题之后,我发现我要的都是dp[target],要么取值,要么计算,要么判断
这个target决定了背包dp的容量–dp[target + 1]
这道题又出现了dp[j] = dp[j - nums[i]] + xxx
上面其实可以总结为,一维背包问题,其中 dp[j] = dp[i] + dp[j - nums[i]]就是状态转移方程
chatGPT老大哥说
解答:
class Solution {
public int findTargetSumWays(int[] nums, int target) {
int sum = Arrays.stream(nums).sum();
if(Math.abs(target) > sum) {
return 0;
}
if((sum + target) % 2 == 1) {
return 0;
}
int mytarget = (sum + target) / 2;
int[] dp = new int[mytarget + 1];
dp[0] = 1;
for(int i = 0; i < nums.length; i++) {
for(int j = dp.length - 1; j >= nums[i]; j--) {
dp[j] += dp[j - nums[i]];
}
}
return dp[mytarget];
}
}
474.一和零
我的思路:
有1和0,是个二维背包问题
这个状态转移方程是dp[i][j] = Math.max(dp[i][j], dp[i - zeroCount][j - oneCount] + 1),而且是在for循环里面更新
解答:
class Solution {
public int findMaxForm(String[] strs, int m, int n) {
int[][] dp = new int[m + 1][n + 1];
for(String s : strs) {
int zeroCount = 0;
int oneCount = 0;
for(char ch : s.toCharArray()) {
if(ch == '0') {
zeroCount++;
}
if(ch == '1') {
oneCount++;
}
}
for(int i = m; i >= zeroCount; i--) {
for(int j = n; j >= oneCount; j--) {
dp[i][j] = Math.max(dp[i][j], dp[i - zeroCount][j - oneCount] + 1);
}
}
}
return dp[m][n];
}
}