算法随想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;
}
posted @ 2023-03-15 13:08  冥紫将  阅读(18)  评论(0)    收藏  举报