思路:可以转化为背包问题。
首先我们看到,题目中要求我们求出目标数的方案数。既然有正数也有负数,那么就一定会从数组中选一部分当负数,选一部分当正数。
假如我们拿z当作选取当正数的元素的和,sum当作全部元素之和。这个时候选取当负数的元素之和那么就是sum-z了,那么目标数是多少呢?其实就是选取当正数的元素之和-选取负数的元素之和。也就是z-(sum-z)=target,我们移动一下就变成了:z=(sum+target)/2。
这个意思也就是说,选取当正数的元素之和恰好为后面这个式子。既然是恰好,那么方案数一定是能被2整除的,也就是上面sum+target一定是个偶数。而且数组里面没有负数,也不可能是负数。
怎么转换成背包问题呢?其实很简单,既然有上面那个式子了,我们在题目中也知道了sum和target,所以也就是说,我们需要从数组中选取能够正好得到z的方案数。即从数组中选取若干数,让这些数的和恰好为z的方案数。
这样的话也就是典型的背包问题求方案数了。
上代码:
class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int n=nums.size();target+=accumulate(nums.begin(),nums.end(),0);//算出sum+targetif(target<0||target%2)//这个数不可能是负数或者奇数return 0;vector<int>f(target+1,0);//状态数组f[0]=1;//由于状态中都是0,在递推过程中需要有至少一个方案数target/=2;//z的值for(int i=0;i<n;i++){for(int j=target;j>=0;j--){if(j<nums[i])f[j]=f[j];elsef[j]=f[j]+f[j-nums[i]];}}return f[target];}
};