代码随想录算法训练营第43天|1049.最后一块石头的重量II,494.目标和

链接: 1049.最后一块石头的重量II
链接: 494.目标和

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

这道题目和分割等和子集很像。关键在于想到如何把石头分为重量相近的两堆。

代码随想录算法训练营第43天|1049.最后一块石头的重量II,494.目标和_第1张图片

class Solution {
    public int lastStoneWeightII(int[] stones) {
       int sum = 0;

       for(int x : stones){
           sum += x;
       }

       int target = sum/2; // 向下取整,所以sum - dp[target] >= dp[target]

       int[] dp = new int[target+1];
        
        // 初始化
        Arrays.fill(dp,0);

        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 sum - 2 * dp[target];
    }
}

494.目标和

做的时候不知道如何推导背包的重量以及如何剪枝。
代码随想录算法训练营第43天|1049.最后一块石头的重量II,494.目标和_第2张图片
代码随想录算法训练营第43天|1049.最后一块石头的重量II,494.目标和_第3张图片

class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        int sum = 0;
        
        for(int x:nums){
            sum += x;
        }
        //如果target过大 sum将无法满足
        if ( target < 0 && sum < -target) return 0;
        if ((target + sum) % 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];
    }
}

总结

代码随想录算法训练营第43天|1049.最后一块石头的重量II,494.目标和_第4张图片

你可能感兴趣的:(算法)