记忆化搜索
class Solution {
public:
int target;
bool dfs(vector<int>& nums, int i, int sum, vector<vector<int>>& memo) {
if (sum > target || i >= nums.size()) return false;
if (sum == target) return true;
int& res = memo[i][sum];
if (res != -1) return memo[i][sum];
// 选
bool choose = dfs(nums, i + 1, sum + nums[i], memo);
// 不选
bool nchoose = dfs(nums, i + 1, sum, memo);
res = choose || nchoose;
return res;
}
bool canPartition(vector<int>& nums) {
target = accumulate(nums.begin(), nums.end(), 0);
if (target % 2 != 0) return false;
target /= 2;
vector<vector<int>> memo(nums.size() + 1, vector<int>(target, -1));
return dfs(nums, 0, 0, memo);
}
};
dp
class Solution {
public:
bool canPartition(vector<int>& nums) {
int sum = accumulate(nums.begin(), nums.end(), 0);
if (sum % 2 != 0) return false;
int target = sum / 2;
vector<int> dp(10001, 0);
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]);
}
}
return dp[target] == target;
}
};