一:题目
二:上码
1:动态规划
class Solution {
public:
/**
思路:1.首先确定完全背包 因为我们可以重复加入
2.动态规划5步走
1>:确定dp数组以及下标的含义
dp[i] 表示的是背包容量为i的时候(这里的 i 也是就是我们的target),有多少种排列数目
2>:确定dp数组的递推公式
这个是统计有多少种 排列的个数,所以我们是需要用到前面求出来的结果
比如 i = 5 的时候,这时放入背包的是 2 那么我们是需要dp[3]的排列结果的
3>:确定dp数组的初始化
dp[0] = 1;
4>:确定dp数组的遍历顺序
如果求组合数就是外层for循环遍历物品,内层for遍历背包。
如果求排列数就是外层for遍历背包,内层for循环遍历物品。
5>:
*/
int combinationSum4(vector<int>& nums, int target) {
vector<int> dp(target+1,0);
dp[0] = 1;
for(int i = 0; i <= target; i++) {//遍历背包
for(int j = 0; j < nums.size(); j++) {//遍历物品
if(i >= nums[j] && dp[i] < INT_MAX - dp[i - nums[j]])//这里需要判断的是防止两个数的和超过最大值
dp[i] += dp[i-nums[j]]; //即dp[i] + dp[i-nums[i]] < INT_MAX
}
}
return dp[target];
}
};
2:回溯暴搜(超时)
记录失败码
class Solution {
public:
/**
思路:
1.确定好回溯函数的返回值和参数
2.确定好回溯函数的递归终止条件
3.确定遍历顺序
*/
vector<vector<int> > ans;
vector<int> path;
void backstacking(vector<int>& nums,int target,int sum) {
// int sum = accumulate(path.begin(),path.end(),0);
if(sum >= target) {
if(sum == target)
ans.push_back(path);
return;
}
for(int i = 0; i < nums.size(); i++) {
path.push_back(nums[i]);
sum+=nums[i];
backstacking(nums,target,sum);
path.pop_back();
sum-=nums[i];
}
}
int combinationSum4(vector<int>& nums, int target) {
backstacking(nums,target,0);
return ans.size();
}
};