494. Target Sum(转换+dp)

https://leetcode.com/problems/target-sum/description/

题目:组成目标数有多少种方法?

思路:

举例说明: nums = {1,2,3,4,5}, target=3, 一种可行的方案是+1-2+3-4+5 = 3

 该方案中数组元素可以分为两组,一组是数字符号为正(P={1,3,5}),另一组数字符号为负(N={2,4})

 因此: sum(1,3,5) - sum(2,4) = target

          sum(1,3,5) - sum(2,4) + sum(1,3,5) + sum(2,4) = target + sum(1,3,5) + sum(2,4)

          2sum(1,3,5) = target + sum(1,3,5) + sum(2,4)

          2sum(P) = target + sum(nums)

          sum(P) = (target + sum(nums)) / 2

 由于target和sum(nums)是固定值,因此原始问题转化为求解nums中子集的和等于sum(P)的方案个数问题。

如果 sum(nums) 小于 S或者 (sum(nums) + S) % 2 !=0 表示不能组成目标数,返回0。

应用dp解决子集合问题:
dp[y]+=dp[y-num],表示组成数值y的方案数等于原来组成数值y的方案数 + 组成数值y-num的方案数

例如
dp[8] = dp[8] + dp[8-1] (假设数组为: 1 2 3 4 5)
dp[8] = dp[8] + dp[8-2]
dp[8] = dp[8] + dp[8-3]
dp[8] = dp[8] + dp[8-4]
dp[8] = dp[8] + dp[8-5]

dp代码

for(int num : nums) 
    for(int y=target;y>=num;y--)
        dp[y]+=dp[y-num];

完整代码:

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int S) {
        int sum = 0;
        for(int num : nums) sum+=num;

        if (sum < S || (sum + S) % 2 != 0)
           return 0;

        int target = (sum+S)>>1;
        int dp[target+1];

        memset(dp,0,sizeof(dp));
        dp[0] = 1;

        for(int num : nums) 
            for(int y=target;y>=num;y--)
                dp[y]+=dp[y-num];

     return dp[target];   
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

计算机的小粽子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值