动态规划五部曲:
1、确定dp数组下标及其含义
dp[j]:总和为j的元素排列数的个数
2、确定递推式
dp[j] += dp[j-nums[i]]
3、如何初始化
dp[0] = 1;
4、确定遍历顺序
内层物品 外层背包 如果外层物品 那么不会出现3,1这样的组合 只有1,3这样的组合
因而内层物品 外层背包 排列数 反之为组合数
可以这么理解 当外层物品 内层背包时 对于每一个背包容量 物品只加入计算1次(按顺序加入计算) 为组合数
5、举例推导dp
dp数组变化:
1 0 0 0 0
1 1 0 0 0
1 1 2 0 0
1 1 2 4 0
1 1 2 4 7
题解:
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
//排列数
//dp[j]:总和为j的元素排列数的个数
//确定递推式:dp[j] += dp[j-nums[i]]
//定义dp数组
vector<int> dp(target+1,0);
//初始化
dp[0] = 1;
//计算dp 内层物品 外层背包 如果外层物品 那么不会出现3,1这样的组合 因而内层物品 外层背包 排列数 反之为组合数
for(int j = 0;j<=target;j++){
for(int i = 0;i<nums.size();i++){
if(j-nums[i]>=0 && dp[j]<INT_MAX-dp[j-nums[i]]){
dp[j]+=dp[j-nums[i]];
}
}
//每计算完一个 将dp打印出来
// for(int x = 0;x<=target;x++){
// cout<<dp[x]<<" ";
// }
// cout<<endl;
}
return dp[target];
}
};