算法day30-动态规划(3)0-1背包

目录

  1. 分割等和子集
  2. 最后一块石头的重量II
  3. 目标和
  4. 1和0

一、分割等和子集

 https://leetcode.cn/problems/partition-equal-subset-sum/?envType=problem-list-v2&envId=8At1GmaZ

 

class Solution {
    public boolean canPartition(int[] nums) {
        //dp[j]:容量为j的背包能装的最大价值为dp[j]
        if(nums == null || nums.length == 0){
            return false;
        }
        int sum = 0;
        for(int x : nums){
            sum += x;
        }
        if(sum % 2 != 0)    return false;
        int target = sum/2;
        //先遍历物品
        int[] dp = new int[target+1];
     dp[0] = 0;
for(int i=0; i<nums.length; i++){ //遍历背包 for(int j=target; j>=nums[i]; j--){ dp[j] = Math.max(dp[j], dp[j-nums[i]]+nums[i]); } } return dp[target] == target; } }

 

二、最后一块石头的重量II

 https://leetcode.cn/problems/last-stone-weight-ii/?envType=problem-list-v2&envId=8At1GmaZ

 

class Solution {
    public int lastStoneWeightII(int[] stones) {
        if(stones == null || stones.length == 0){
            return 0;
        }
        int sum = 0;
        for(int x : stones){
            sum += x;
        }
        int target = sum/2;
        int[] dp = new int[target+1];
     dp[0] = 0;
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 Math.abs(dp[target]-(sum-dp[target])); } }

 

三、目标和(装满这个背包有多少种方法)

 https://leetcode.cn/problems/target-sum/?envType=problem-list-v2&envId=8At1GmaZ

 

class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        //dp[j]:装满容量为j的背包有dp[j]种方法
        int sum = 0;
        for(int i=0; i<nums.length; i++){
            sum += nums[i];
        }
        if(Math.abs(target) > sum)  return 0;
        //left+right = sum;
        //left - right = target;
        //left = (sum+target)/2;
        if((sum+target) % 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--){
                // 1 -- dp[4] -> dp[5]
    
                dp[j] += dp[j-nums[i]];
            }
        }
        return dp[bagSize];
    }
}    

 

四、1和0(装满这个背包有多少个物品)

 https://leetcode.cn/problems/ones-and-zeroes/?envType=problem-list-v2&envId=8At1GmaZ

 

class Solution {
    public int findMaxForm(String[] strs, int m, int n) {
        //dp[i][j]:装满i个0、j个1最多背了dp[i][j]个物品
        int[][] dp = new int[m+1][n+1];
        dp[0][0] = 0;
        //遍历物品
        for(String s : strs){
            int x=0, y=0;
            for(char c : s.toCharArray()){
                if(c == '0'){
                    x++;
                }else{
                    y++;
                }
            }
            //遍历背包
            for(int i=m; i>=x; i--){
                for(int j=n; j>=y; j--){
                    dp[i][j] = Math.max(dp[i][j], dp[i-x][j-y]+1);
                }
            }
        }
        return dp[m][n];
    }
}

 

posted @ 2025-06-01 00:23  筱倩  阅读(253)  评论(0)    收藏  举报