参考资料:代码随想录
这道题开题解给我看的一脸懵,最后还是靠着手动画图才稍微明白。
本次和最后一块石头的重量2有异曲同工之妙,都是要分成两堆。难点1就是想到这个方面。
怎么转为背包问题。
正数的集合总和-负数的集合总和=目标和,那么怎么求出正数的集合;
负数的集合总和=总和-正数的集合总和。
所以,正数的集合总和-(总和-正数的集合总和)=目标和
所以,正数的集合总和=(总和+目标和)/2。
正数的集合总和=最大背包重量
1.确定dp数组含义
定义一个最大背包整理的大小的数组
含义为,0-n重量分别有几种组合方式。
2.初始化dp数组
因为是求方式数,dp[0]初始化为1,不用非得死扣为什么为1,知道是为了推出正确答案才这么初始化就够了。
3.确定遍历顺序
因为每个元素只能使用一次,所以倒序遍历。
4.确定递推公式
很难解释含义,只能靠带入递推公式,手动画表格理解。
class Solution {public int findTargetSumWays(int[] nums, int target) {//确定最大重量int sum = Arrays.stream(nums).sum();if(Math.abs(target) > sum) return 0;if((target+sum)%2 == 1) return 0;int maxWeight = (target+sum)/2;//1.确定dp数组含义int[] dp = new int[maxWeight+1];//2.初始化Dp数组dp[0] = 1;//3.确定遍历顺序for(int i = 0;i < nums.length;i++){for(int j = maxWeight;j >= nums[i];j--){dp[j] += dp[j-nums[i]];}}return dp[maxWeight];}
}