首先,子集合求和问题的定义是,给定一个数组,共有n个数;
那么,对于前i个数,在总量j的限定下,最多能装多少?
class Solution {
public int dp(int[]nums,int s){
int len=nums.length;
int[][]target=new int[len+1][s+1];
target[0][0]=1;//对于0个数,要达到总量0,是可以的,有一种方法
for(int i=1;i<=len;i++){
for (int j=0;j<=s;j++){
//当有i个数,要达到j;首先,前i-1个数,在总量为j情况下的方法,有target[i-1][j]种(种数可能为0)
//然后,当要包含第i个数然后仍然达到j,那换句话说,就是i-1个数达到j-nums[i-1]的重量(这里,nums[i-1]就是第i个数的重量)
//因此,最后将这两种情况的和相加,即,i个数的总量和为j的所有情况
target[i][j]=target[i-1][j];
if(j-nums[i-1]>=0)target[i][j]+=target[i-1][j-nums[i-1]];
}
}
//最后的答案应该是,len个数,总量s的情况总数!
return target[len][s];
}
public int findTargetSumWays(int[] nums, int S) {
int sum=0;
for(int n:nums)sum+=n;
return sum<S||(sum+S)%2==1?0:dp(nums,(sum+S)>>1);
}
}