LeetCode494 目标和

  • 题目描述:

给你一个整数数组 nums 和一个整数 target 。

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

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

链接:https://leetcode.cn/problems/target-sum

  • 示例

输入: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

  • 算法思想

该题是01背包问题的变体,我们可以先求出nums数组的总和为sum,然后设需要加 '+' 的那些数的和为A,需要加 '-' 的那些数的和为B,那么sum=A+B,target=A-B,从而A=(sum+target)/2,所以原问题就转化为在nums数组中选出一些数并使其和为A的方案数。

  • 代码
 1 #include<iostream>
 2 #include<vector>
 3 using namespace std;
 4 int main(){
 5     vector<int> nums;
 6     int target;
 7     int n;
 8     cin >> n;
 9     int x;
10     for (int i = 0; i < n; i++) {
11         cin >> x;
12         nums.push_back(x);
13     }
14     cin >> target;
15     int sum = 0;
16     for (int i = 0; i < nums.size(); i++)
17             sum += nums[i];
18     if (target > sum || target < -sum) return 0; // 肯定不行
19         //a必须为整数,所以target+sum必须为偶数
20     if ((target + sum) & 1) return 0; // 奇数
21     int a = (target + sum) >> 1;
22     vector<int> dp(a + 1, 0);
23     dp[0] = 1;
24     for (int i = 1; i <= nums.size(); i++) {
25          for (int j = a; j >= nums[i - 1]; j--) {
26              dp[j] = dp[j] + dp[j - nums[i - 1]];
27          }
28     }
29     cout << dp[a]<< endl;
30 }

 

posted on 2023-03-15 10:29  _月生  阅读(25)  评论(0)    收藏  举报