代码随想录算法训练营第四十二天 | 背包问题、416. 分割等和子集

93 阅读1分钟

代码随想录算法训练营第四十二天 | 背包问题、416. 分割等和子集

二维背包数组:

dp[i][j]含义从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。

一维数组:(很抽象)

  1. 背包遍历需要倒序,如果因为右边的值需要依赖左边的覆盖前的值。
  2. 先遍历物品再遍历重量,这样可以使每个物品都放进背包,如果调换顺序,那么美个重量j下只放了一个物品。

416. 分割等和子集

题目链接:416. 分割等和子集

  • 转化成01背包的问题

     class Solution {
     public:
         bool canPartition(vector<int>& nums) {
             int sum = 0;
             for (int num: nums) {
                 sum += num;
             }
             if(sum % 2 != 0) return false;
             int target = sum / 2;
             int len = nums.size();
             vector<vector<int>> dp(len + 1, vector<int>(target + 1)); // 对于前i个物品, 当前背包容量为w,这时候可以装的最大价值为 dp[i][w];
             for (int i = 1; i <= len; i++) {
                 for(int j = 1; j <= target; j++) {
                     if (j >= nums[i - 1]) {
                         dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - nums[i - 1]] + nums[i - 1]);
                     } else {
                         dp[i][j] = dp[i - 1][j];
                     }
                 }
             }
             if(dp[len][target] == target) {
                 return true;
             } else {
                 return false;
             }
         }
     };