算法随想Day37【动态规划】| LC416-分割等和子集
动态规划五部曲
- 确定dp[i]的含义
- dp递推公式
- dp数组如何初始化
- 确认dp数组遍历顺序
- 打印dp数组,主要用于调试
LC416. 分割等和子集
这道题是“背包问题”的应用,但其实不好看出来。
-
dp[i]的含义和递推公式 与 01背包问题一致。
-
这道题的dp数组中,物品的weight即为价值
-
注意的细节,如判断if (nums[i] > j) continue;比如说在背包为5kg的时候不能对一个6kg的物品进行相减判断,否则会造成数组左越界

bool canPartition(vector<int>& nums)
{
int sum = 0;
int size = nums.size();
for (int i = 0; i < size; ++i)
{
sum += nums[i];
}
if (sum & 1 != 0 || size == 1) //不是2的倍数
{
return false;
}
int weight = sum >> 1; //背包的重量
////这道题的dp中,物品的weight即为价值
vector<int> dp(weight + 1, 0);
//for (int i = 0; i < size; ++i) 一维dp数组全初始化为0即可
////dp[i]表示容量为weight的包中,存得最大值
for (int i = 0; i < size; ++i)
{
for (int j = weight; j >= 1; --j)
{
if (nums[i] > j) continue;
dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);
}
if (dp[weight] == weight)
{
return true;
}
}
return false;
}

浙公网安备 33010602011771号