代码随想录算法训练营day36
1.最后一块石头的重量
1.1 题目
https://leetcode.cn/problems/last-stone-weight-ii/description/
1.2 题解
class Solution
{
public:int lastStoneWeightII(vector<int>& stones) {int sum = 0;for (const auto& i : stones){sum += i;}int tmp = sum / 2; //可以看作背包容量//确定dp数组,dp[j]表示背包容量为j所能装的最大价值vector<int> dp(1501, 0);//确定递推逻辑//dp[j]=max(dp[j]+dp[j-stones[i]]+stones[i]//初始化//遍历for (int i = 0; i < stones.size(); i++){for (int j = tmp; j >= stones[i]; j--){dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);}}int result = dp[tmp];return sum - 2 * result;}
};
2.目标和
2.1 题目
https://leetcode.cn/problems/target-sum/description/
2.2 题解
class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {//取正符号的集合是left,取负符号的集合是right,则有// left-right=target,left+right=sum,所以有sum=2*left-target,left=(sum+target)/2//题目可以转化为背包容量为left,有几种方法将他装满int sum = 0;for (const auto& i : nums){sum += i;}int left = (sum + target) / 2;if ((sum + target) % 2 != 0)return 0;if(abs(target)>sum)return 0;//确定dp数组,dp[j]表示背包容量为j装满这个背包的方法个数vector<int> dp(left+1, 0);//确定递推规律//dp[j]+=dp[j-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]];}}return dp[left];}
};
3.一和零
3.1 题目
https://leetcode.cn/problems/ones-and-zeroes/description/
3.2 题解
class Solution
{
public:int findMaxForm(vector<string>& strs, int m, int n) {//确定dp数组,两个维度,一个维度为0的个数,一个维度为1的个数//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-x][j-y]+1);//初始化dp[0][0] = 0;//遍历for (const auto& str : strs){int x =0, y = 0;for (const auto& s : str){if (s == '0')x++;if (s == '1')y++;}for (int i = m; i >= x; i--){for (int j = n; j >= y; j--){dp[i][j] = max(dp[i][j], dp[i - x][j - y] + 1);}}}return dp[m][n];}
};