2023.8.14
一杯茶,一包烟,一道dp做一天...
ps:nums[i]均大于等于0。本题先转化为0-1背包问题:将数组元素分成两堆:一堆为正号,另一堆为负号。设正号堆的和为x,则负号堆的和为sum-x。(sum为数组元素总和)。 于是:x-(sum-x) =target ,可以推出 x = (target+sum)/2 。x必须为偶数,为奇数直接返回0。
于是此时背包的大小相当于x,物品为数组nums。 dp[i]的含义为:装满大小为 i 的背包的 方法种数。 具体代码如下:
class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int sum = 0;for(int i=0; i<nums.size(); i++){sum += nums[i];}if((sum + target) % 2 == 1) return 0;int capacity = (sum + target)/2;if(capacity < 0) return 0;vector<int> dp(capacity + 1);dp[0] = 1;for(int i=0; i<nums.size(); i++){for(int j=capacity; j>=nums[i]; j--){//第一项是不使用nums[i]时装满背包的方法种数,第二项是使用nums[i]时装满背包的方法种数。dp[j] = dp[j] + dp[j - nums[i]];}}return dp[capacity];}
};