第四十三天|1049. 最后一块石头的重量 II 494. 目标和 474. 一和零
1049. 最后一块石头的重量 II
其实还是尽量把背包装满
class Solution {
public:
int lastStoneWeightII(vector<int>& stones) {
int sum=0;
for(int a:stones){
sum+=a;
}
int target=sum/2;
vector<int> dp(target+1,0);
for(int i=0;i<stones.size();i++){
for(int j=target;j>=stones[i];j--){
dp[j]=max(dp[j],dp[j-stones[i]]+stones[i]);
}
}
return sum-2*dp[target];
}
};
494. 目标和
如何转化为01背包问题呢。
假设加法的总和为x,那么减法对应的总和就是sum - x。
所以我们要求的是 x - (sum - x) = target
x = (target + sum) / 2
所以求容量为x的背包有几种装满方式
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int target) {
int sum=0;
for(int a:nums){
sum+=a;
}
if((sum+target)%2==1)return 0;
int s=(sum+target)/2;
if(abs(target )>sum)return 0;
vector<int> dp(s+1,0);
dp[0]=1;
for(int i=0;i<nums.size();i++){
for(int j=s;j>=nums[i];j--){
dp[j]+=dp[j-nums[i]];
}
}
return dp[s];
}
};
474. 一和零
有两个参数的01背包,求最多装多少
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 st:strs){
int zero=0;
int one=0;
for(int i=0;i<st.size();i++){
if(st[i]=='0')zero++;
else one++;
}
for(int i=m;i>=zero;i--){
for(int j=n;j>=one;j--){
dp[i][j]=max(dp[i][j],dp[i-zero][j-one]+1);
}
}
}
return dp[m][n];
}
};