由于nums中元素全为正数,设nums所有元素之和为sum,加号之和为x,则减号的绝对值之和为sum-x,则
x-(sum-x)=target
得到x=(sum+target)/2
所以问题变成:在nums中选择子集,使得子集之和为x的方案数量。
dp[i][j]: 0~i下标中选择,使得子集和为j的方案数
转移方程:
dp[i][j]=dp[i-1][j]+dp[i-1][j-nums[i]]
跟0-1背包中的转移方程很像:dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[j])
所以只需要采用0-1背包的固定格式,只需要更改转移方程即可
class Solution {
public int findTargetSumWays(int[] nums, int target) {
int sum=0;
for(int num:nums) sum+=num;
if(Math.abs(target)>sum) return 0;
if((target+sum)%2==1) return 0;
int k=(target+sum)/2;
int[] dp=new int[k+1];
dp[0]=1;
for(int i=0;i<nums.length;i++){
for(int j=k;j>=nums[i];j--){
dp[j]+=dp[j-nums[i]];
}
}
return dp[k];
}
}