动态规划五步法:
1、确定dp[j]及其下标的含义
dp[j]:容量为j的背包 装满有多少种方法
2、确定递推式
dp[j] = dp[j-nums[i]];
3、如何初始化
dp[0] = 1;//容量为0的背包只有一种方法
4、确定遍历顺序
nums放在外循环、target放在内循环 且内循环倒序遍历
5、推导dp数组
这里就不推导了
i: 0 1 2 3 4
dp:1 5 10 10 5
题解:
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int target) {
//目标和 令 left = 正数之和 right=负数之和 则target = left-right
//而left + right = sum(数组元素之和) 因而 right可由sum-left来表达 故target = left-(sum-left)
//left = (target+sum)/2; 如此 转化为01背包问题 装满left重量的背包有多少种方法 注意到整除 奇数时无解
//求数组和
int n = nums.size();
int sum = 0;
for(int i = 0;i<n;i++){
sum += nums[i];
}
int left = (sum+target)/2;
if((sum+target)%2 == 1){
//奇数 无解
return 0;
}
//定义dp
vector<int> dp(left+1);
//初始化dp 容量为0 一种方法
dp[0] = 1;
//否则 递推式
//dp[j]为背包容量为j时的方法数 它可以由dp[j-nums[i]]得到 累加得到
//求解dp
for(int i = 0;i<n;i++){
for(int j=left;j>=nums[i];j--){
dp[j] +=dp[j-nums[i]];
}
}
//所求即为 dp[left]
return dp[left];
}
};