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];
}
};