day45
70.爬楼梯
题目连接:70. 爬楼梯
解题思路:参考
之前做过的爬楼梯题目,这次可以用完全背包来完成,动态规划五部曲
1.确定dp[j]及下标含义:容量为j的背包最多有多少种方法能装满
2.确定递推公式:dp[j] += dp[j-nums[i]];
3.初始化:dp[0] = 1;如果初始化为0则之后全为0
4.确定遍历顺序:类似排列问题先遍历背包在遍历物品
5.打印dp数组
class Solution {
public:
int climbStairs(int n) {
// 按照完全背包理论处理
vector<int> nums = {1,2};
vector<int> dp(n+1,0);
dp[0] = 1;
for( int j = 0; j <= n; j++){
for( int i = 0; i < nums.size(); i++){
if( j >= nums[i]){
dp[j] += dp[j - nums[i]];
}
}
}
return dp[n];
}
};
//复习之前的版本
class Solution {
public:
int climbStairs(int n) {
// // 按照完全背包理论处理
// vector<int> nums = {1,2};
// vector<int> dp(n+1,0);
// dp[0] = 1;
// for( int j = 0; j <= n; j++){
// for( int i = 0; i < nums.size(); i++){
// if( j >= nums[i]){
// dp[j] += dp[j - nums[i]];
// }
// }
// }
// return dp[n];
if( n <= 2) return n;
int dp[2];
dp[0] = 1;
dp[1] = 2;
int sum ;
for( int i = 3; i <= n; i++){
sum = dp[0] + dp[1];
dp[0] = dp[1];
dp[1] = sum;
}
return dp[1];
}
};
322.零钱兑换
题目链接:322. 零钱兑换
第一次做的时候根据之前的思路,直接ac了,稀里糊涂
递归五部曲:
1.dp[j]及下标含义:装满容量为j的背包所需的最少的硬币数量
2.确定递推公式:dp[j] = min( dp[j],dp[j-coins[i]]+1)
3.初始化:dp[0] = 0;其他需要用min来覆盖,因此初始化为INT_MAX
4.遍历顺序:组合问题,先遍历物品再遍历背包
5.打印dp数组
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount+1,0);
dp[0] = 0;
for( int i = 1; i <= amount; i++){
dp[i] = INT_MAX;
}
for( int i = 0; i < coins.size(); i++){
for( int j = coins[i]; j <= amount; j++){
if(dp[j-coins[i]] < INT_MAX - 1)//注意这里有个临界条件需要比较,也就是保证其不能越界
dp[j] = min(dp[j],dp[j-coins[i]] + 1);
}
}
return dp[amount] == INT_MAX ? -1 : dp[amount];
}
};
先遍历物品,再遍历背包,求组合数
先遍历背包,再遍历物品,求排列数
279.完全平方数
题目链接:279. 完全平方数
和上一题一模一样
还是相同的套路,第一遍直接ac,本题要注意如何确定物品数组,题目已经给出了范围,因此直接求即可。
class Solution {
public:
int numSquares(int n) {
vector<int> nums(101,0);
for( int i = 1; i <= 100; i++){
nums[i] = i*i;
}
vector<int> dp(n+1,0);
dp[0] = 0;
for( int i = 1; i <= n; i++){
dp[i] = INT_MAX;
}
for( int i = 0; i < nums.size(); i++){
for( int j = nums[i]; j <= n; j++){
if( dp[j - nums[i]] < INT_MAX - 1)
dp[j] = min( dp[j] ,dp[j - nums[i]] + 1);
}
}
return dp[n];
}
};
// 数组有点多余,还增加了时间和空间复杂度,直接用数值替代即可
class Solution {
public:
int numSquares(int n) {
vector<int> dp(n+1,INT_MAX);
dp[0] = 0;
for( int i = 0; i <=100; i++){
for( int j = i*i; j <= n; j++){
if( dp[j - i*i] < INT_MAX - 1)
dp[j] = min( dp[j] ,dp[j - i*i] + 1);
}
}
return dp[n];
}
};