LeetCode35● 1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零

1049.最后一块石头的重量II

力扣题目链接

尽可能装满

class Solution {
    public int lastStoneWeightII(int[] stones) {
        //分成两个尽量相等的等份就可以使剩下的石头尽可能的小。
        //dp[] 最后的出来的是最接近一半的偏小的那部分
        //dp[j] 表示能装i的背包里面能装的最大价值(重量)
        //dp[j] = Math.max(dp[i],dp[j - stones[i]] + stones[i])
        //初始化。dp[j] = 0
        //从j = 0遍历,内部背包,外部物品
        //内部要反着遍历

        int sum = 0;
        for(int i = 0;i < stones.length;i++){
            sum += stones[i];
        }
        int[] dp = new int[(sum / 2) +  1];
        for(int i = 0;i < stones.length;i++){
            for(int j = sum / 2;j >= 0;j--){
                if(j >= stones[i])
                dp[j] = Math.max(dp[j],dp[j - stones[i]] +stones[i]);
            }
        }
        return sum - dp[sum / 2] - dp[sum / 2];
    }
}

494.目标和

力扣题目链接

class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        //左子树-右子树 = target,如何确定左右子树有哪些数字
        //left - right = target,一个数是奇数(sum),那么他只能拆为奇数加偶数, 二者之差为奇数(target)。 sum + target为偶数
                                //一个数是偶数,那么他能拆为两个奇数或两个偶数,二者之差为偶数。
                                //同样 sum + target
        //所以sum + target必须是偶数
        
        //left + right = sum
        //left = (sum + target) / 2
        //从num中找出等于left的数量
        //dp[j]代表装满j的最大组合数量。
        //dp[j] += dp[j - nums[i]]; 
        //dp[0] = 1;

        int sum = 0;
        
        for(int i = 0;i < nums.length;i++){
            sum += nums[i];
        }
    
        if(target < 0 && sum < -target || target > 0 && sum < target)return 0;

        if((sum + target) % 2 != 0)return 0;

        int size = (sum + target) / 2;

        
        int[] dp = new int[size + 1]; 
        dp[0] = 1;
        for(int i = 0;i < nums.length;i++){
            for(int j = size;j >= nums[i];j--){
                dp[j] += dp[j - nums[i]];
            }
        }
        return dp[size];
    }
}

474.一和零

力扣题目链接

class Solution {
    public int findMaxForm(String[] strs, int m, int n) {
        //dp[i][j] 表示背包容量为ij时的最大子集个数    i个0,j个1
        //dp[i][j] = max(dp[i][j],dp[i - numsi][j - numj] + 1)
        //全部初始化为0
        //先遍历物品,再遍历背包
        int [][] dp = new int[m + 1][n + 1];
        for(String s : strs){

            //计算这个物品的重量(几个i 几个 j)
            int num0 = 0;
            int num1 = 0;
            for(int i = 0;i < s.length();i++){
                if(s.charAt(i) == '0')num0++;
                else if(s.charAt(i) == '1')num1++;
            }
            for(int i = m;i >= num0;i--){
                for(int j = n;j >= num1;j--){
                    dp[i][j] = Math.max(dp[i][j],dp[i - num0][j - num1] + 1);
                }
            }
        }
        return dp[m][n];

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值