算法day30-动态规划(3)0-1背包
目录
- 分割等和子集
- 最后一块石头的重量II
- 目标和
- 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]; } }
浙公网安备 33010602011771号