494. 目标和¶
给你一个非负整数数组 nums
和一个整数 target
。
向数组中的每个整数前添加 '+'
或 '-'
,然后串联起所有整数,可以构造一个 表达式 :
- 例如,
nums = [2, 1]
,可以在2
之前添加'+'
,在1
之前添加'-'
,然后串联起来得到表达式"+2-1"
。
返回可以通过上述方法构造的、运算结果等于 target
的不同 表达式 的数目。
示例 1:
Text Only | |
---|---|
示例 2:
提示:
1 <= nums.length <= 20
0 <= nums[i] <= 1000
0 <= sum(nums[i]) <= 1000
-1000 <= target <= 1000
个人题解¶
动态规划(滚动数组)¶
dp[j]
表示装满容量为j
的背包有dp[j]
种方法;- 递推公式:
dp[j] += dp[j - nums[i]]
,推导见下一部分; - 初始化
dp[0] = 1
,即装满容量为0
的背包有1
种方法,因为该背包没有容量,天然是满的; - 遍历顺序见 416. 分割等和子集,有详细说明;
- 手动推导
dp
数组无误。
组合类问题的 dp
递推公式¶
回到本题,不妨将 nums[i]
作为 weight[i]
那么有 dp[3] = dp[0] + dp[1] + dp[2]
。
因为要装满容量为 3
的背包,无非有三种情况:
nums[i] = 1
时,有dp[2]
种办法装满背包。因为由dp
数组的定义知,装满容量为2
的背包有dp[2]
种方法,此时再把当前nums[i]
装入背包,不就装满容量为3
的背包了吗 ;- 同理,
nums[i] = 2
时,有dp[1]
种办法装满背包; nums[i] = 3
时,有dp[0]
种办法装满背包。
故装满容量为 3
的背包有 dp[3] = dp[0] + dp[1] + dp[2]
种方法,以此类推,得到通用递推公式:dp[j] += dp[j - nums[i]]
。