day42

1、leetcode1049 最后一块石头的重量Ⅱ

  • 思路

    • 尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小

    • 转化为01背包问题:从stones 数组中选择,凑成总和不超过sum/2的最大价值。

      • 其中「重量」&「价值」均为数值本身。
  • 代码

    • class Solution {
          public int lastStoneWeightII(int[] stones) {
              int sum = 0;
              for(int stone : stones) {
                  sum += stone;
              }
      
              int target = sum / 2;
              int[] dp = new int[target+1];
      
              for(int i=0; i<stones.length; i++) {
                  for(int j=target; j>=stones[i]; j--) {
                      dp[j] = Math.max(dp[j], dp[j-stones[i]]+stones[i]);
                  }
              } 
      
              return sum - dp[target] - dp[target];
          }
      }
      

2、leetcode494 目标和

  • 思路

    • 将nums数组中的数组分为两组,pos(+)、neg(-)

      • pos + neg = sum

      • pos - neg = target

      • sum、target已知 ===》 pos = (sum + target) / 2

    • 将问题转化为:装满容量为pos的背包,有几种方法。

  • 代码

    • class Solution {
          public int findTargetSumWays(int[] nums, int target) {
              int sum = 0;
              for(int num : nums) sum += num;
      
              if(Math.abs(target) > sum) return 0;
              if((target + sum) % 2 == 1) return 0;
      
              int bagSize = (target+sum)/2;
              int dp[] = new int[bagSize+1];
              dp[0] = 1;
      
              for(int i=0; i<nums.length; i++) {
                  for(int j=bagSize; j>=nums[i]; j--) {
                      dp[j] += dp[j - nums[i]];
                  }
              }
      
              return dp[bagSize];
          }
      }
      

3、leetcode474 一和零

  • 思路

    • 转化为01背包(多维背包)

      • strs 数组里的元素就是物品,每个物品都是一个,且每个物品的价值为1(对答案的贡献价值为1)

      • m、n相当于是刻画背包容量的两个维度

  • 代码

    • class Solution {
          public int findMaxForm(String[] strs, int m, int n) {
              int dp[][] = new int[m+1][n+1];
              int zeroNum = 0;
              int oneNum = 0;
              for(String str : strs) {
                  zeroNum = 0;
                  oneNum = 0;
                  for(char ch : str.toCharArray()) {
                      if(ch == '0') {
                          zeroNum++;
                      } else {
                          oneNum++;
                      }
                  }
      
                  for(int i=m; i>=zeroNum; i--) {
                      for(int j=n; j>=oneNum; j--) {
                          dp[i][j] = Math.max(dp[i][j], dp[i-zeroNum][j-oneNum] + 1);
                      }
                  }
              }
      
              return dp[m][n];
      
          }
      }
      
posted @   黄三七  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示