代码随想录第三十八天
动态规划五部曲
1、确定dp[i]每个元素的含义和下标含义
2、写出递推公式
3、初始化dp数组
4、确定遍历顺序
5、模拟打印
509. 斐波那契数
斐波那契数,通常用 F(n) 表示,形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) = 0,F(1) = 1 F(n) = F(n - 1) + F(n - 2),其中 n > 1 给你n ,请计算 F(n) 。
1、dp[i]对应第i个斐波那契数值
2、递推公式:dp[i]=dp[i-1]+dp[i-2]
3、初始化:dp[0]=0,dp[1]=1
4、从左向右进行遍历
5、模拟打印数组
代码如下:
int Fibonacci(int n)
{
if (n == 0)
return 0;
if (n == 1)
return 1;
vector<int>dp;
dp.push_back(0);
dp.push_back(1);
for (int i=2;i<=n;i++)
{
int tmp = dp[i - 1] + dp[i - 2];
dp.push_back(tmp);
}
return dp[n];
}
70. 爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
1、dp[i]:到达第i个阶梯拥有的办法
2、递推公式:dp[i]=dp[i-1]+dp[i-2]
3、初始化:dp[0]=1,dp[1]=1,或者dp[1]=1,dp[2]=2
4、从左向右进行遍历
5、模拟打印数组
代码如下:
int climbStair(int n)
{
if (n ==0)
return 1;
if (n == 1)
return 1;
vector<int>dp;
dp.push_back(1);
dp.push_back(1);
for (int i=2;i<=n;i++)
{
int tmp = dp[i - 1] + dp[i - 2];
dp.push_back(tmp);
}
return dp[n];
}
746. 使用最小花费爬楼梯
数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值 cost[i](下标从 0 开始)。
每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯。
请你找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为 0 或 1 的元素作为初始阶梯。
1、dp[i]:到达第i个阶梯所花的最小精力
2、递推公式:dp[i]=min(dp[i-1],dp[i-2])+cost[i]
3、初始化:dp[0]=cost[0],dp[1]=cost[1]
4、从左向右进行遍历
5、模拟打印数组
代码如下:
int minFeeOfClimbStair(vector<int>& cost)
{
if (cost.size() == 1)return cost[0];
if (cost.size() == 2)return min(cost[0], cost[1]);
vector<int>dp;
dp.push_back(cost[0]);
dp.push_back(cost[1]);
for (int i=2;i<=cost.size()-1;i++)
{
int tmp = min(dp[i - 1], dp[i - 2]) + cost[i];
dp.push_back(tmp);
}
int size = dp.size()-1;
return min(dp[size], dp[size - 1]);
}