zoukankan      html  css  js  c++  java
  • 刷题-力扣-494. 目标和

    494. 目标和

    题目链接

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/target-sum/
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    题目描述

    给你一个整数数组 nums 和一个整数 target 。
    向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 :

    例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。
    返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。

    示例 1:

    输入:nums = [1,1,1,1,1], target = 3
    输出:5
    解释:一共有 5 种方法让最终目标和为 3 。
    -1 + 1 + 1 + 1 + 1 = 3
    +1 - 1 + 1 + 1 + 1 = 3
    +1 + 1 - 1 + 1 + 1 = 3
    +1 + 1 + 1 - 1 + 1 = 3
    +1 + 1 + 1 + 1 - 1 = 3
    

    示例 2:

    输入:nums = [1], target = 1
    输出:1
    

    提示:

    • 1 <= nums.length <= 20
    • 0 <= nums[i] <= 1000
    • 0 <= sum(nums[i]) <= 1000
    • -1000 <= target <= 100

    题目分析

    1. 根据题目描述计算数组部分和减去剩下部分和等于target的不同的组合数
    2. 用N表示负数部分和,P表示正数部分和。有N+P=sum(nums),P-N=target,N=P-target,2*N=P-target+N,N=(sum(nums)-target)/2
    3. 使用动态规划求解,dp[i][j]表示nums的前i个数的和等于j的情况个数。状态转移方程为,
      当j<nums[i-1]时,dp[i][j]=dp[i-1][j];
      当j>=nums[i-1]时,dp[i][j]=dp[i-1][j]+dp[i-1][j-nums[i-1]]
    4. 边界条件,
      当i=0,j=0时,dp[i][j]=1;
      当i=0,j!=0时,dp[i][j]=0

    代码

    class Solution {
    public:
        int findTargetSumWays(vector<int>& nums, int target) {
            int numsSum = 0;
            int numsLen = nums.size();
            for (auto n : nums) numsSum += n;
            if ((numsSum - target) < 0 || (numsSum - target) % 2 != 0) return 0;
            int neg = (numsSum - target) / 2;
            vector<vector<int>> dp(numsLen + 1, vector<int>(neg + 1, 0));
            dp[0][0] = 1;
            for (int i = 1; i <= numsLen; ++i) {
                for (int j = 0; j <= neg; ++j) {
                    if (j < nums[i - 1]) {
                        dp[i][j] = dp[i - 1][j];
                    } else {
                        dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i - 1]];
                    }
                }
            }
            return dp[numsLen][neg];
        }
    };
    
  • 相关阅读:
    BZOJ 3506 机械排序臂 splay
    BZOJ 2843 LCT
    BZOJ 3669 魔法森林
    BZOJ 2049 LCT
    BZOJ 3223 文艺平衡树 splay
    BZOJ 1433 假期的宿舍 二分图匹配
    BZOJ 1051 受欢迎的牛 强连通块
    BZOJ 1503 郁闷的出纳员 treap
    BZOJ 1096 ZJOI2007 仓库设计 斜率优化dp
    BZOJ 1396: 识别子串( 后缀数组 + 线段树 )
  • 原文地址:https://www.cnblogs.com/HanYG/p/14858492.html
Copyright © 2011-2022 走看看