动态规划理论基础
文章链接:动态规划理论基础
思想:动态规划五部曲-
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
Leetcode 509.斐波那契数
题目链接:509.斐波那契数
递归法解题思路:递归法比较简单就不说了,就是按着他给的题意初始化,然后设计跳出条件,并进入递归
动态规划解题思路:首先确定dp数组以及下标的含义,dp数组的含义就是斐波那契数列,下标为i就是第i个斐波那契数。递推公式就是dp[i] = dp[i - 1] + dp[i - 2],初始化就是dp[0] = 0, dp[1]。然后遍历顺序就是从前往后遍历。第五个打印数组没啥问题
动态规划法:
class Solution {
public:
int fib(int n) {
if(n <= 1) return n;
vector<int> dp(n + 1);
dp[0] = 0, dp[1] = 1;
for(int i = 2; i <= n; i++) dp[i] = dp[i - 1] + dp[i - 2];
return dp[n];
}
};
- 时间复杂度为O(n)
- 空间复杂度为O(n)
动态规划状态压缩法:
class Solution {
public:
int fib(int n) {
if(n <= 1) return n;
int dp[2];
dp[0] = 0, dp[1] = 1;
for(int i = 2; i <= n; i++) {
int sum = dp[0] + dp[1];
dp[0] = dp[1];
dp[1] = sum;
}
return dp[1];
}
};
- 时间复杂度为O(n)
- 空间复杂度为O(1)
递归法:
class Solution {
public:
int fib(int n) {
if(n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
};
- 时间复杂度为O(2^n)
- 空间复杂度为O(n)
Leetcode 70.爬楼梯
题目链接:70.爬楼梯
解题思路:类似斐波那契数,dp数组以及下标含义为爬到第i层阶,有dp[i]种方法,递推公式为dp[i] = dp[i-1] + dp[i-2],初始化的话限制了不会出现0的情况,因此初始化为dp[1] = 1, dp[2] = 2即可;遍历顺序为从前往后开始遍历
class Solution {
public:
int climbStairs(int n) {
if(n <= 1) return n;
vector<int> dp (n + 1);
dp[1] = 1, dp[2] = 2;
for(int i = 3; i <= n; i++) dp[i] = dp[i-1] + dp[i-2];
return dp[n];
}
};
- 时间复杂度为O(n)
- 空间复杂度为O(n)
状态压缩:
class Solution {
public:
int climbStairs(int n) {
if(n <= 1) return n;
int dp[2];
dp[0] = 1, dp[1] = 2;
for(int i = 3; i <= n; i++) {
int sum = dp[0] + dp[1];
dp[0] = dp[1];
dp[1] = sum;
}
return dp[1];
}
};
- 时间复杂度为O(n)
- 空间复杂度为O(1)
Leetcode 746.使用最小花费爬楼梯
题目链接:746.使用最小花费爬楼梯
解题思路:dp数组以及下标的含义为,到达第i个台阶所花费的最少体力为i,只有开始爬的时候才消耗体力,所以递推公式为dp[i] = min(dp[i-1] + cost[I-1], dp[i-2] + cost[I-2]);初始化为dp[0] = 0 , dp[1]=0,因为可以选择第0个位置或者第1个位置开始爬楼梯。遍历顺序为从前往后遍历。
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
if(cost.size() <= 2) return min(cost[0], cost[1]);
vector<int> dp(cost.size() + 1);
dp[0] = 0, dp[1] = 0;
for(int i = 2; i <= cost.size(); i++) {
dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]);
}
return dp[cost.size()];
}
};
- 时间复杂度为O(n)
- 空间复杂度为O(n)
状态压缩:
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
if(cost.size() <= 2) return min(cost[0], cost[1]);
int dp[2];
dp[0] = 0, dp[1] = 0;
for(int i = 2; i <= cost.size(); i++) {
int sum = min(dp[1] + cost[i-1], dp[0] + cost[i-2]);
dp[0] = dp[1];
dp[1] = sum;
}
return dp[1];
}
};
- 时间复杂度为O(n)
- 空间复杂度为O(1)
本文详细介绍了动态规划在解决斐波那契数列、爬楼梯和最小花费爬楼梯问题中的应用,包括dp数组的定义、递推公式、初始化和遍历顺序,同时展示了两种空间复杂度优化的方法——常规和状态压缩。

被折叠的 条评论
为什么被折叠?



