代码随想录算法训练营第四十三天|动态规划part05|1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零

1049. 最后一块石头的重量 II Last Stone Weight II - LeetCode

dp[j] 背量 j 最大价dp[j]

                  最大重量dp[j]

dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]

dp[0] = 0;

for (int i = 0; i < stones.length; i++) //物品

        for(int j = target; j >= stones[i]; j--) //背包容量

打印dp数组

class Solution {
    public int lastStoneWeightII(int[] stones) {
        int sum = 0;
        for (int s : stones) {
            sum += s;
        }
        
        int target = sum / 2;
        //初始化,dp[i][j]为可以放0-i物品,背包容量为j的情况下背包中的最大价值
        int[][] dp = new int[stones.length][target + 1];
        //dp[i][0]默认初始化为0
        //dp[0][j] 取决于stones[0]
        for (int j = stones[0]; j <= target; j++) {
            dp[0][j] = stones[0];
        }

        for (int i = 1; i < stones.length; i++) {
            for (int j = 1; j <= target; j++) {
                if (j >= stones[i]) {
                    //不放:dp[i - 1][j] 放:dp[i - 1][j - stones[i]] + stones[i]
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - stones[i]] + stones[i]);
                } else {
                    dp[i][j] = dp[i - 1][j];
                }
            }
        }
        return sum - 2*dp[stones.length - 1][target];

    }
}

                

●  494. 目标和 Target Sum - LeetCode

dp[j] 装满为j的背包有dp[j]种方法

正数集合

负数集合

left + right = sum;

left - right = target;

right = sum - left;

left - (sum - left) = target;

left = (target + sum) / 2;

1 dp[4]种方法凑成dp[5]

2 dp[3]种方法凑成dp[5]

3 dp[2]种方法凑成dp[5]

4 dp[1]种方法凑成dp[5]

5 dp[0]

dp[5] = dp[4] + dp[3] + dp[2] + dp[1] + dp[0]

dp[j] += dp[j - nums[i]]

dp[0] = 1;

for (int i = 0; i < nums.length; i++)

        for(j = bagSize; j >= nums[i];j--)

class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        int sum = 0;
        for (int n : nums) {
            sum += n;
        }
        if (target < 0 && sum < -target) return 0;
        if ((target + sum) % 2 != 0) return 0;
        int bagSize = (target + sum) / 2;
        if (bagSize < 0) bagSize = -bagSize;
        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];
    }
}

        

●  474.一和零  Ones and Zeroes - LeetCode

dp[i][j] i 个 0, j个1 最大背dp[i][j]物品

dp[i - x][j - y] + 1 //物品里面的0和1

物品的重量就是x个0,y 个1

dp[i][j] = max(dp[i - x][j - y] + 1, dp[i][j])

dp[0][0] = 0

for (Strng s : : strs) //遍历的是物品

        int x = 0, y = 0;

        for (char c : str)

                if (c == '0') x++;

                else y++;

        for (i = m; i >= x; i--)//遍历的是背包容量

                for(j = n; j >= y; j--)

 打印dp数组

class Solution {
    public int findMaxForm(String[] strs, int m, int n) {
        //dp[i][j]表述i个0和j个1时的最大子集
        int[][] dp = new int[m + 1][n + 1];
        int one;
        int zero;
        for (String s : strs) {
            one = 0;
            zero = 0;
            for (char c : s.toCharArray()) {
                if (c == '0') {
                    zero++;
                } else {
                    one++;
                }
             }
        //倒序遍历
            for (int i = m; i >= zero; i--) {
                for (int j = n; j >= one; j--) {
                    dp[i][j] = Math.max(dp[i][j], dp[i - zero][j - one] + 1);
                }
            }
        }
        return dp[m][n];
    }
}

                       

你可能感兴趣的:(代码随想录算法训练营,算法,动态规划)