今日收获:动态规划理论基础,斐波那契数,爬楼梯,使用最小花费爬楼梯
1. 动态规划理论基础(源自代码随想录)
(1)动态规划中当前状态是由上一个状态推导出来的,而贪心是直接选局部最优的
(2)动态规划五部曲:
-
确定dp数组(dp table)以及下标的含义
-
确定递推公式
-
dp数组如何初始化
-
确定遍历顺序
-
举例推导dp数组
2. 斐波那契数
题目链接:509. 斐波那契数 - 力扣(LeetCode)
思路:dp数组存储第n个数的斐波那契数列的值,初始化和递推公式题目中都有给出;每个数的计算都依赖前两个数,所以是从前向后遍历。
方法:
class Solution {
public int fib(int n) {
if (n<=1){
return n;
}
// dp数组
int[] dp=new int[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];
}
}
3. 爬楼梯
思路:dp数组表示上第n层台阶的方法,从前向后遍历,可以得到上第n层台阶的方法就是上第n-1层的方法加上第n-2层的方法。
方法:
class Solution {
public int climbStairs(int n) {
if (n<=2){
return n;
}
int[] dp=new int[n+1]; // 第n个台阶的方法
dp[0]=0;
dp[1]=1;
dp[2]=2;
for (int i=3;i<=n;i++){
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n];
}
}
4. 使用最小花费爬楼梯
题目链接:746. 使用最小花费爬楼梯 - 力扣(LeetCode)
思路:dp数组记录爬上第i个台阶所需要的最小花费,初始第0和1个台阶不需要花费。从前向后遍历,第i个台阶的最小花费取从第i-1个台阶和第i-2个台阶上来花费的最小值。
方法:
class Solution {
public int minCostClimbingStairs(int[] cost) {
int[] dp=new int[cost.length+1]; // 到达第i个台阶的最小花费
dp[0]=0;
dp[1]=0;
for (int i=2;i<=cost.length;i++){
dp[i]=Math.min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
}
return dp[cost.length];
}
}
总结:dp数组记录的值含义和求的值相同,比如这道题求第n个台阶的最小花费,那dp数组存储的就是到达第i个台阶的最小花费。