1、DFS暴力超时
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int S) {
return dfs(nums,S,0);
}
int dfs(vector<int>& nums,uint target,int left)
{
if(target == 0 && left == nums.size())return 1;
if(left >= nums.size())return 0;
int ans = 0;
ans += dfs(nums,target-nums[left],left+1);
ans += dfs(nums,target+nums[left],left+1);
return ans;返回值
}
};
2、
P(ADD) - P(SUB) = T
SUM + P(ADD) - P(SUB) = T + SUM 推出 P(ADD) - P(SUB) + P(ADD) - P(SUB) = T + SUM
2P(ADD) = T + SUM
P(ADD) = (T + SUM)/2转换为0/1背包问题求P(ADD)存在个数
一维数组压缩解法:
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int S) {
int sum = 0;
for(auto c : nums)
{
sum += c;
}
if(sum < S || (sum + S)%2 == 1)return 0; // 若是奇数或者数组元素总和小于S,则无解
int w = (sum + S)/2;
vector<int> dp(w+1+0);
dp[0] = 1; // 初始状态值:若刚好取到sum,则方案数加1
for(auto c : nums)
{
for(int j = w; j >= c; j--)
{
dp[j] += dp[j-c];// 01背包,一维数组实现,逆序枚举,保证每个元素都被只用一次
}
}
return dp[w];
}
};
二维解法:
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int S) {
int sum = 0;
for(auto c : nums)
{
sum += c;
}
if(sum < S || (sum + S)%2 == 1)return 0;
int w = (sum + S)/2;
int n = nums.size();
vector<vector<int>> dp(n+1,vector<int>(w+1,0));
for(int i=0;i<=n;i++){
dp[i][0]=1;
}
for(int i = 1; i < n+1; i++)
{
for(int j = 0; j <= w; j++)
{
if(j-nums[i-1]<0)//表示当前容量j装不下
{
dp[i][j]=dp[i-1][j];
}else{
dp[i][j]=dp[i-1][j]+dp[i-1][j-nums[i-1]];
}
}
}
return dp[n][w];
}
};
num[i]\容量j | 0 | 1 | 2 | 3 | 4 |
0 | 1 | 0 | 0 | 0 | 0 |
1-1 | 1 | 1 | 0 | 0 | 0 |
2-1 | 1 | 2 | 1 | 0 | 0 |
3-1 | 1 | 3 | 3 | 1 | 0 |
4-1 | 1 | 4 | 6 | 4 | 1 |
5-1 | 1 | 5 | 10 | 10 | 5 |
3、