【LeetCode】每日一题2021/11/26

本文探讨了一种新颖的背包问题,涉及目标值和数组元素的加减操作。通过转化为01背包问题并运用回溯或动态规划,作者介绍了如何处理加减组合,以及状态转移方程的调整。实例和总结强调了将问题分解和子问题处理的重要性。
摘要由CSDN通过智能技术生成

0
1

  • 思路
    这道题一样有重叠子问题,然后我们看到它有一个target,一个数组,数组里的数字只能用一次,所以考虑01背包问题求解。
    这道题,要找到所有的情况,就是要穷举,也可想到回溯的办法来穷举所有的情况。
    target就是背包的最大容量,然后数组nums[i]加上符号一起构成了物品的重量和物品的价值。
    考虑dp五要素:
    dp的数组定义与下标含义:dp[target+1],代表对应的背包容量下满足价值等于,其中下标含义是背包容量;
    dp的状态转移方程:dp[j]=max(dp[j],dp[j-nums[i]]+nums[i]);
    dp的初始化:都初始化为0;
    dp的遍历顺序:外层物品i=0;i<nums.length;i++,内层背包容量j=target;j>=nums[i];j–;
    举例推导
    考虑到这里就发现困难了,上述感觉不太对。
    参考题解
    这里最难的是想到有加有减,怎么来处理呢?如果只有加或减一种是不是就更好处理呢?
    所以依旧是考虑把加减分为两部分。
    2
    01

3
4
5

class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        int sum = 0;
        // 求总和
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
        }
        // 这是推导出的为+的数字的总和
        // 要满足bagSize = (sum + target) / 2,如果不能够整除说明数字是凑不上的
        if ((sum + target) % 2 == 1) {
            return 0;
        }
        // 如情况[100] -200
        if (Math.abs(target) > sum) {
            return 0;
        }
        // 要得到的总和,即添加+得到的总和
        int bagSize = (sum + target) / 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--) {
                dp[j] += dp[j - nums[i]];
            }
        }
        return dp[bagSize];
    }
}

6

  • 总结
    其实到这里,发现背包问题很多时候都不是能够直接就能想到办法来解决,很多时候都是要处理一下,分为子问题,变成两部分,拿一部分来做背包去与另一部分进行相应的呼应。
    这道题又是一种新的题型是在背包中加入组合问题,在dp数组定义和状态转移方程就有所区别。
    还需要多加练习。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kaimar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值