前言
LeetCode题目:LeetCode 70、322、279
Takeaway:背包问题——完全背包问题,内外循环的顺序很重要,决定了是求排列还是求组合。
外物品内重量:组合(因为1号物品肯定在2号之前);
外重量内物品:排列(1号物品可以在2号之后,不一定);
和昨天几乎没区别,就是新学会了,当求最小方法时,初始化应该初始成INT_MAX
一、70
完全背包求排列问题,具体看注释。
class Solution {
public:
int climbStairs(int n) {
// 边界处理
if(n<=1){
return n;
}
// DP含义是:爬到第j层,有多少种方法
vector<int> dp(n + 1);
dp[0] = 1;
// 排列问题,先重量,后物品
for(int j=0; j<=n; j++){
for(int i=1;i<=2;i++){
if(j >= i){
dp[j] += dp[j-i];
}
}
}
return dp[n];
}
};
二、322
完全背包求组合问题,具体看注释,由于是求最小方法数量,所以初始化成INT_MAX。
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
// DP数组含义为:凑成 j 所用的硬币数最低为多少
vector<int> dp(amount + 1, INT_MAX);
dp[0] = 0;
//这是个组合问题,外层为物品,内层是重量
for(int i=0; i<coins.size(); i++){
for(int j=coins[i]; j<=amount; j++){
dp[j] = min(dp[j-coins[i]]+1, dp[j]);
}
}
if (dp[amount] == INT_MAX)
return -1;
return dp[amount];
}
};
三、279
完全背包求组合问题,具体看注释,由于是求最小方法数量,所以初始化成INT_MAX。
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
// DP数组含义为:凑成 j 所用的硬币数最低为多少
vector<int> dp(amount + 1, INT_MAX);
dp[0] = 0;
//这是个组合问题,外层为物品,内层是重量
for(int i=0; i<coins.size(); i++){
for(int j=coins[i]; j<=amount; j++){
dp[j] = min(dp[j-coins[i]]+1, dp[j]);
}
}
if (dp[amount] == INT_MAX)
return -1;
return dp[amount];
}
};
总结
背包问题——完全背包问题,内外循环的顺序很重要,决定了是求排列还是求组合。
外物品内重量:组合(因为1号物品肯定在2号之前);
外重量内物品:排列(1号物品可以在2号之后,不一定);
和昨天几乎没区别,就是新学会了,当求最小方法时,初始化应该初始成INT_MAX