力扣--动态规划01背包问题494.目标和

前提核心:
将全部数组分为两组,一组为取正数的(zheng),一组取负数的(fu);
可知:
zheng+fu=all
zheng-fu=target
那么zheng=(all+target)/2
如果all+target不能被2整除,就代表没办法使得zheng的数组和-fu的数组和为target,即返回0。

dp[i]表示正数数组和为i时有dp[i]种取法。

---------------------------------------------------------------------------------------------------------------------------------
※确定递推公式

只要搞到nums[i],凑成dp[j]就有dp[j - nums[i]] 种方法。

例如:dp[j],j 为5,

  • 已经有一个1(nums[i]) 的话,有 dp[4]种方法 凑成 容量为5的背包。
  • 已经有一个2(nums[i]) 的话,有 dp[3]种方法 凑成 容量为5的背包。
  • 已经有一个3(nums[i]) 的话,有 dp[2]中方法 凑成 容量为5的背包
  • 已经有一个4(nums[i]) 的话,有 dp[1]中方法 凑成 容量为5的背包
  • 已经有一个5 (nums[i])的话,有 dp[0]中方法 凑成 容量为5的背包

那么凑整dp[5]也就是把 所有的 dp[j - nums[i]] 累加起来。

---------------------------------------------------------------------------------------------------------------------------------

思路分析:

  1. 首先,计算数组 nums 中所有元素的和,存储在 all 变量中。
  2. 如果目标值 target 的绝对值大于数组元素和 all,则无法找到解,直接返回0。
  3. 如果目标值 target 与数组元素和 all 之和为奇数,也无法找到解,直接返回0。
  4. 计算目标和的一半,存储在 zheng 变量中,这是要达到的目标。
  5. 创建一个大小为 zheng+1 的动态规划数组 dp,并初始化 dp[0] 为1,表示和为0的组合有一种可能。
  6. 使用动态规划算法来计算达到目标和 zheng 的组合数。通过遍历数组 nums,在每次迭代中,更新 dp 数组以记录达到各个和值的组合数。
  7. 最后,返回 dp[zheng],即达到目标和 zheng 的组合数,这就是问题的解。
     

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int target) {
        int zheng, all = 0; // 定义变量zheng和all,分别用于存储目标值和数组中所有元素的和
        int i, j;

        // 计算数组中所有元素的和
        for (i = 0; i < nums.size(); i++)
            all += nums[i];

        // 如果目标值的绝对值大于数组元素和,无法找到解,返回0
        if (abs(target) > all)
            return 0;

        // 如果目标值与数组元素和之和为奇数,也无法找到解,返回0
        if ((all + target) % 2 == 1)
            return 0;
        else
            zheng = (all + target) / 2; // zheng表示目标和的一半,这是要达到的目标

        // 创建一个大小为zheng+1的动态规划数组dp,初始化为0
        vector<int> dp(zheng + 1, 0);
        dp[0] = 1; // dp[0]初始化为1,表示和为0的组合有一种可能

        // 使用动态规划来计算达到目标和zheng的组合数
        for (i = 0; i < nums.size(); i++) {
            for (j = zheng; j >= nums[i]; j--) {
                dp[j] += dp[j - nums[i]]; // 更新dp数组,累加可能的组合数
            }
        }

        return dp[zheng]; // 返回达到目标和zheng的组合数
    }
};

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值