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];
}
};