1049.最后一块石头的重量
题目链接 文章讲解 视频讲解
解题思路:
将石头尽量分为相等的两堆,两堆最差即为所求结果
石头的重量就是石头的价值
动规五部曲:
- dp[j]:表示背包容量为j时可以装的石头的总价值
- 递推公式:dp[j] = max(dp[j], dp[j-stones[i]] + stones[i]
- 初始化:均初始化为0
- 遍历顺序:先遍历石头后遍历背包
- 打印dp数组
class Solution {
public:int lastStoneWeightII(vector<int>& stones) {int weight = 0;for(int val : stones) weight += val;int capcity = weight / 2;// dp[j] 表示容量为j的背包装的石头的总价值最大为多少vector<int> dp(capcity + 1);for(int j = 0; j <= capcity; ++j) dp[j] = 0;// 递推公式: dp[j] = max(dp[j], dp[j-weight[i]] + value[i])// 初始化:均初始化为0for(int j = 0; j < capcity; ++j) dp[j] = 0;// 先遍历石头后遍历背包for(int i = 0; i < stones.size(); ++i) {for(int j = capcity; j >= stones[i]; --j) {dp[j] = max(dp[j], dp[j-stones[i]] + stones[i]);}}return weight - (dp[capcity] << 1);}
};
494.目标和
题目链接 文章讲解 视频讲解
思路:将数组分为两个集合left全部存整数,target全部存负数
那么满足:left + right = sum; left - right = target;
计算得left = (sum + target) / 2;
left即为背包的容量
动规五部曲:
- dp[j]:装满容量为j的背包有dp[j]种方法
- 递推公式:dp[j] += dp[j - nums[i]]
- 初始化:dp[0] = 1, 其他初始化为0
- 遍历顺序:先遍历物品后遍历背包,背包倒序遍历
- 打印dp数组
class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int sum = 0;for(int val : nums) sum += val;if((sum + target) % 2 == 1) return 0;if(abs(target) > sum) return 0;int left = (sum + target) >> 1;// dp[j]: 表示容量为j的背包装哪些数可以正好装满vector<int> dp(left + 1, 0);// 递推公式: dp[j] = dp[j], dp[j - nums[i]] + nums[i];// 初始化dp[0] = 1;for(int i = 0; i < nums.size(); ++i) {for(int j = left; j >= nums[i]; --j) {dp[j] += dp[j - nums[i]];}}for(int val : dp) cout << val << " ";return dp[left];}
};
474.一和零
题目链接 文章讲解 视频讲解
- dp[i][j]: 表示装满i个0和j个1最多可以装dp[i][j]个物品
- 递推公式:dp[i][j] = max(dp[i - x][j - y], dp[i][j])
- 初始化:均初始化为0
- 遍历顺序:先遍历物品后遍历背包
- 打印dp数组
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 - x][j - y] + 1, dp[i][j])// 初始化 dp[i][j] = 0// 遍历顺序,先遍历物品后遍历背包for(string str : strs) {int x = 0, y = 0;for(char ch : str) {if(ch == '0') ++x;else ++y;}// 遍历背包for(int i = m; i >= x; --i) { for(int j = n; j >= y; --j) dp[i][j] = max(dp[i - x][j - y] + 1, dp[i][j]);}}return dp[m][n];}
};