前言
LeetCode题目:LeetCode 518、377
Takeaway:背包问题——完全背包问题,内外循环的顺序很重要,决定了是求排列还是求组合。
外物品内重量:组合(因为1号物品肯定在2号之前);
外重量内物品:排列(1号物品可以在2号之后,不一定);
一、518
完全背包问题——求组合,DP数组含义是:凑成DP[j]有多少种方法;由于是求组合,外层应该是物品,内层才是重量。
class Solution {
public:
int change(int amount, vector<int>& coins) {
//初始化DP数组,DP含义是:凑成DP[j]有多少种方法
vector<int> dp(amount + 1, 0);
dp[0] = 1;
for(int i=0; i<coins.size(); i++){
for(int j=coins[i]; j<=amount; j++){
//dp[j] 为 不取coins[i] 和 取coins[i] 中方法数最多的那个
dp[j] += dp[j-coins[i]];
}
}
return dp[amount];
}
};
二、377
完全背包问题——求排列,DP数组含义是:凑成DP[j]有多少种方法;由于是求排列,外层循环是重量,内层循环是物品。
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
// DP数组含义:构成 j 有多少种方法
vector<int> dp(target + 1, 0);
dp[0] = 1;
for(int j=0; j<=target; j++){
for(int i=0; i<nums.size(); i++){
if(j >= nums[i] && dp[j] < INT_MAX - dp[j - nums[i]]){
dp[j] += dp[j-nums[i]];
}
}
}
return dp[target];
}
};
总结
背包问题——完全背包问题,内外循环的顺序很重要,决定了是求排列还是求组合。
外物品内重量:组合(因为1号物品肯定在2号之前);
外重量内物品:排列(1号物品可以在2号之后,不一定);