LeetCode 416 分割等和子集
题目链接:https://leetcode.cn/problems/partition-equal-subset-sum/
思路:
暴力解法-回溯,最后结果是超时。
01背包
将数组里元素的值分布作为其重量和价值,目的是求背包容量为0.5sum(sum是数组总和)时,其最大价值是否是0.5sum。是的话返回true,否则返回false。
dp[j]代表背包容量为j时的最大价值
接下来就是01背包的解题过程。关键在于要将其变成01背包。
代码:
回溯
class Solution {
private:
int result;
bool backtracking(vector<int>&nums,int startindex,int sum)
{
if(result==sum)
return true;
for(int i = startindex;i<nums.size();i++)
{
result += nums[i];
sum -= nums[i];
if(backtracking(nums,i+1,sum)) return true;
result -= nums[i];
sum += nums[i];
}
return false;
}
public:
bool canPartition(vector<int>& nums) {
int sum = 0;
for(int i = 0;i<nums.size();i++)
sum += nums[i];
return backtracking(nums,0,sum);
}
};
01背包
class Solution {
public:
bool canPartition(vector<int>& nums) {
int sum = 0;
vector<int>dp(10001,0);
sum = accumulate(nums.begin(),nums.end(),0);
if(sum%2==1) return false; // 如果总和为奇数的话,不可能能分出两个子集来
int target = sum/2;
for(int i = 0;i<nums.size();i++)
{
for(int j = target;j>=nums[i];j--)
dp[j] = max(dp[j],dp[j-nums[i]]+nums[i]);
}
if(dp[target]==target)
return true;
else
return false;
}
};
总结
01背包的应用,需要多学习。
今日总结:
今天学习01背包,大概了解了要求什么东西,和为什么代码这么写。遍历顺序,初始化,递推公式在二维数组和一维数组时都有什么含义,需要多加记忆和理解。