任务日期:7.11
题目一链接:1049. 最后一块石头的重量 II - 力扣(LeetCode)
思路:本题是背包问题解决一定容量的背包里最多能放多少?。本题抽象为有n种物品,将他们尽可能均分成两堆,用容量为sum/2的背包装物品,最后返回包里的和剩余的物品重量的差值即可。
代码:
class Solution {
public:
int lastStoneWeightII(vector<int>& stones) {
//转化为有n种物品,将他们尽可能的均分成两堆,这样差值最小,最后返回两堆的差值;这里就不需要判断sum是奇是偶了,因为这都无所谓,最后算的差值
vector<int> dp(1501,0);//容量最大是3000,但这里最大的容量是1500就行
dp[0] = 0;
int sum = 0;
for(int i = 0;i < stones.size();i ++) {
sum += stones[i];
}
int target = sum / 2;
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]);//因为dp坐标内是减法,所以前面的dp值会影响后面的值,因此倒序j先算后面的值,不会对前面的值产生影响。
}
}
return sum - dp[target] - dp[target];
}
};
难点:
解释细节1:背包问题能计算出在一定背包容量下的最大的重量或者最大价值
题目二链接:494. 目标和 - 力扣(LeetCode)
思路:本题抽象为求装满容量为x的背包的方法数。x是数组中正数元素的加和,由两个公式推导出来。
代码:
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int target) {
int sum = 0;
for(int i = 0;i < nums.size();i ++) {
sum += nums[i];
}
int x = (target + sum) / 2;
if((target + sum) % 2 != 0) return 0;
if(abs(target) > sum) return 0;
vector<int> dp(x + 1,0);//此时的dp[j]代表装满容量为j的背包的方法有多少种
//dp[j] += dp[j - nums[i]];
dp[0] = 1;//记住,如果是0的话后面的值都是0
for(int i = 0;i < nums.size();i ++) {
for(int j = x;j >= nums[i];j --) {
//背包问题计算的方法数的公式
dp[j] += dp[j - nums[i]];
}
}
return dp[x];
}
};
难点:
解释细节1:dp[j]代表用物品装满j重量的背包的方法数。
题目三链接:474. 一和零 - 力扣(LeetCode)
思路:装满一个背包用的最大物品数。这道题可以抽象为一道背包问题,只是比一般背包问题的容量多了一个维度,这里有两个容量:1的个数和0的个数,同时物品的种类是每段单独的字符串。明白这个后再套用背包问题的模版。
代码:
class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
//dp[i][j]:i代表0的个数 j代表1的个数
vector<vector<int>> dp(m + 1,vector<int>(n + 1,0));//全部初始化为零
//确定递推公式
//dp[i][j] = max(dp[i][j],dp[i - zeroNum][j - oneNum] + 1);
for(string str : strs) {//遍历物品:每个字符相当于一个物品
int oneNum = 0,zeroNum = 0;
for(char c : str) {
if(c == '0') zeroNum ++;
else oneNum ++;
}
//遍历背包容量:对0 1 的容量进行遍历
//递推顺序:容量倒序递推
for(int i = m;i >= zeroNum;i --) {
for(int j = n;j >= oneNum;j --) {
dp[i][j] = max(dp[i][j],dp[i - zeroNum][j - oneNum] + 1);//选当前的元素的情况:先减去当前元素0的个数再减去1的个数然后dp再加1
}
}
}
return dp[m][n];
}
};
难点:
解释细节1: