题目描述
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/59b1e062ad41eeae6ad09edab93993bc.png)
思路
- 和前面那道题一样,将dp[ i ][ j ]定义为从数组nums中 0 - i 的元素进行加减可以得到 j 的方法数量。
- 这道题的关键不是nums[i]的选与不选,而是nums[i]是加还是减,那么我们就可以将方程定义为:
- dp[ i ][ j ] = dp[ i - 1 ][ j - nums[ i ] ] + dp[ i - 1 ][ j + nums[ i ] ]
dp数组的定义
- 一般背包问题的定义都是dp[len][t+1],而这次则不一样
- 因为最低是取全负数,最高是取全正数,所以应该总共可能出现
sum*2+1(1为相加为0的情况)种可能性,故取为dp[len][sum*2+1]
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0a5eb4f67a4a819a0ee391e0c5176efc.png)
- 最后返回的应为:dp[len - 1][sum + s]。
代码
public int findTargetSumWays(int[] nums, int target) {
int sum=0;
for(int i=0;i<nums.length;i++) {
sum+=nums[i];
}
if(Math.abs(target)>Math.abs(sum)) return 0;
int[][] dp = new int[nums.length][sum*2+1];
if(nums[0]==0) {
dp[0][sum]=2;
}else {
dp[0][sum+nums[0]]=1;
dp[0][sum-nums[0]]=1;
}
for(int i=1;i<nums.length;i++) {
for(int j=0;j<sum*2+1;j++) {
int l,r;
if(j-nums[i]>=0) l = j-nums[i];
else l=0;
if(j+nums[i]<sum*2+1) r = j+nums[i];
else r=0;
dp[i][j] = dp[i-1][l]+dp[i-1][r];
}
}
return dp[nums.length-1][sum+target];
}