目录
🎈动态规划理论基础
贪心与动规的区别:
贪心:局部最优---全局最优
动规:每一个状态由上一个状态推导而来(有递推公式)
✨动态规划的解题步骤
动规五部曲:
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
🎈LeetCode509.斐波那契数
链接:509.斐波那契数
斐波那契数 (通常用
F(n)
表示)形成的序列称为 斐波那契数列 。该数列由0
和1
开始,后面的每一项数字都是前面两项数字的和。也就是:F(0) = 0,F(1) = 1 F(n) = F(n - 1) + F(n - 2),其中 n > 1给定
n
,请计算F(n)
。
解法一:递归
//递归法
public int fib(int n) {
if(n==0){
return 0;
}
if(n==1){
return 1;
}
return fib(n-1)+fib(n-2);
}
解法二:迭代法
public int fib(int n) {
if(n==0){
return 0;
}
if(n==1){
return 1;
}
int first=0;
int second=1;
int third=0;
for(int i=2;i<=n;i++){
third=first+second;
first=second;
second=third;
}
return third;
}
解法三:动态规划
public int fib(int n) {
if(n==0){
return 0;
}
if(n==1){
return 1;
}
// 1.确定dp数组及下标含义
// dp[i]表示第i个斐波那契数列是多少
int[] dp=new int[n+1];
// 2.确定递推公式
// dp[i]=dp[i-1]+dp[i-2]
// 3.初始化
dp[0]=0;
dp[1]=1;
// 4.确定遍历顺序
for(int i=2;i<=n;i++){
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n];
}
🎈 LeetCode70.爬楼梯
链接:70.爬楼梯
假设你正在爬楼梯。需要
n
阶你才能到达楼顶。每次你可以爬
1
或2
个台阶。你有多少种不同的方法可以爬到楼顶呢?
ublic int climbStairs(int n) {
// dp[i]表示爬i阶台阶用dp[i]种方法
int[] dp=new int[n+1];
// 递推公式:dp[i]=dp[i-1]+dp[i-2]
// 初始化
dp[0]=1;
dp[1]=1;
// 遍历
for(int i=2;i<=n;i++){
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n];
}
🎈 LeetCode746.使用最小的花费爬楼梯
给你一个整数数组
cost
,其中cost[i]
是从楼梯第i
个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。你可以选择从下标为
0
或下标为1
的台阶开始爬楼梯。请你计算并返回达到楼梯顶部的最低花费。
public int minCostClimbingStairs(int[] cost) {
// dp[i]表示爬i个台阶的最小费用
int[] dp=new int[cost.length+1];
// dp[i]=Math.min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
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];
}