算法刷题记录 Day36
Date: 2024.04.02
lc 416. 分割等和子集
c++
//2. 一维数组
class Solution {
public:
bool canPartition(vector<int>& nums) {
// 将问题转化为从数组中任意取数,使得容量为数组总和一半的背包内的价值尽可能大。
// dp[j]表示容积为j的背包中,能装的最大价值。
// dp[j] = for(int i=n-1; i>=0; i++) max(dp[j], dp[j-nums[i]]+nums[i]);
int n = nums.size();
int count = 0;
for(auto& x: nums){
count += x;
}
int half_count = count / 2;
vector<int> dp(half_count+1, 0);
for(int i=0; i<n; i++){
for(int j=half_count; j>=nums[i]; j--){
dp[j] = max(dp[j], dp[j-nums[i]]+nums[i]);
}
}
if(dp[half_count] == (count - half_count))
return true;
else
return false;
}
};
// 1. 二维数组
class Solution {
public:
bool canPartition(vector<int>& nums) {
// 将问题转化为从数组中任意取数,使得容量为数组总和一半的背包内的价值尽可能大。
// dp[i][j] 表示从第[0, i]个数中,容积为j的背包的最大价值;
// dp[i][j] = max(dp[i-1][j], dp[i-1][j-v[i]]+v[i]);
// 初始化第一行中,j大于等于nums[0]的为j,其余为0;
int n = nums.size();
int count = 0;
for(auto& x: nums){
count += x;
}
int half_count = count / 2;
vector<vector<int>> dp(n, vector<int>(half_count+1, 0));
for(int j=nums[0]; j<=half_count; j++){
dp[0][j] = nums[0];
}
for(int i=1; i<n; i++){
for(int j=0; j<=half_count; j++){
if(j < nums[i])
dp[i][j] = dp[i-1][j];
else{
dp[i][j] = max(dp[i-1][j], dp[i-1][j-nums[i]]+nums[i]);
}
}
}
// for(int i=0; i<n; i++){
// for(int j=0; j<=half_count; j++){
// cout<<"i:"<<i<<", j:"<<j<<", value:"<<dp[i][j]<<endl;
// }
// }
if(dp[n-1][half_count] == (count - half_count))
return true;
else
return false;
}
};