目录
1137. 第 N 个泰波那契数
分析
代码
面试题 08.01. 三步问题
分析
代码
746. 使用最小花费爬楼梯
分析
代码
泰波那契序列 Tn 定义如下:
T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2
给你整数 n
,请返回第 n 个泰波那契数 Tn 的值。
示例 1:
输入:n = 4 输出:4 解释: T_3 = 0 + 1 + 1 = 2 T_4 = 1 + 1 + 2 = 4
示例 2:
输入:n = 25 输出:1389537
分析
根据题目中的Tn+3 = Tn + Tn+1 + Tn+2,可以转换为n>=3时,Tn = Tn-1+ Tn-2 + Tn-3。
在求解动态规划的题目时,我们可以分为五个步骤:
1.状态表示
状态表示简而言之就是dp表里面某个值所代表的含义。
要得到dp表,基本上可以按照题目要求、做题经验、发现重复子问题三个步骤。
针对这个题目,可以根据题目要求得出,dp[i]表示第 i 个泰波那契数。
2.状态转移方程
状态转移方程就是得到 dp[i] 等于什么。
这个题目中比较明显,dp[i]=dp[i-1]+dp[i-2]+dp[i-3]
3.初始化
初始化就是为了保证后续填dp表的时候不越界。
这个题目中就需要先填 dp[0]=0,dp[1]=1,dp[2]=1
4.填表顺序
为了填写当前状态的时候,所需要的状态已经计算过了。
这个题目已经给出了前三个状态的值,所以就按照从左向右的顺序进行填表。
5.返回值
这个也是由题目要求和前面的状态表示来决定。
这个题目中就可以直接返回 dp[n]。
代码
class Solution {
public:
int tribonacci(int n) {
vector<int>nums(n,0);
//初始化
nums[0]=0;
nums[1]=1;
nums[2]=1;
//填表
for(int i=3;i<=n;i++)
nums[i]=nums[i-1]+nums[i-2]+nums[i-3];
return nums[n];
}
};
面试题 08.01. 三步问题
三步问题。有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模1000000007。
示例1:
输入:n = 3 输出:4 说明: 有四种走法
示例2:
输入:n = 5 输出:13
提示:
- n范围在[1, 1000000]之间
分析
1.状态表示
状态表示简而言之就是dp表里面某个值所代表的含义。
针对这个题目,可以根据题目要求得出,dp[i]表示到达第i个位置时,一共有多少种方法。
2.状态转移方程
这个题目要根据 i 位置的状态,最近的一步来划分问题。
3.初始化
初始化就是为了保证后续填dp表的时候不越界。
根据题干 dp[1]=1,dp[2]=2,dp[3]=4
4.填表顺序
为了填写当前状态的时候,所需要的状态已经计算过了。
这个题目已经给出了前三个状态的值,所以就按照从左向右的顺序进行填表。
5.返回值
这个也是由题目要求和前面的状态表示来决定。
这个题目中就可以直接返回 dp[n]。
代码
class Solution {
public:
int waysToStep(int n) {
long long mod=1000000007;
vector<long long>dp(n+5);
//初始化
dp[1]=1,dp[2]=2,dp[3]=4;
//填表
for(int i=4;i<=n;i++)
{
dp[i]=((dp[i-1]+dp[i-2])%mod+dp[i-3])%mod;
}
return dp[n];
}
};
746. 使用最小花费爬楼梯
给你一个整数数组 cost
,其中 cost[i]
是从楼梯第 i
个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0
或下标为 1
的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
示例 1:
输入:cost = [10,15,20] 输出:15 解释:你将从下标为 1 的台阶开始。 - 支付 15 ,向上爬两个台阶,到达楼梯顶部。 总花费为 15 。
示例 2:
输入:cost = [1,100,1,1,1,100,1,1,100,1] 输出:6 解释:你将从下标为 0 的台阶开始。 - 支付 1 ,向上爬两个台阶,到达下标为 2 的台阶。 - 支付 1 ,向上爬两个台阶,到达下标为 4 的台阶。 - 支付 1 ,向上爬两个台阶,到达下标为 6 的台阶。 - 支付 1 ,向上爬一个台阶,到达下标为 7 的台阶。 - 支付 1 ,向上爬两个台阶,到达下标为 9 的台阶。 - 支付 1 ,向上爬一个台阶,到达楼梯顶部。 总花费为 6 。
分析
1.状态表示
经验+题目要求
针对这个题目,可以根据题目要求得出,dp[i]表示到达 i 位置时的最小花费。
2.状态转移方程
主要是用之前或者之后的状态来推导 dp[i] 的值。
这里根据最近的一步,来划分问题。
3.初始化
初始化就是为了保证后续填dp表的时候不越界。
根据题干 dp[1]=0,dp[1]=0
4.填表顺序
为了填写当前状态的时候,所需要的状态已经计算过了。
根据题目可以得出前两个个状态的值,所以就按照从左向右的顺序进行填表。
5.返回值
这个也是由题目要求和前面的状态表示来决定。
这个题目中就可以直接返回 dp[n]。
代码
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int n=cost.size();
vector<int>dp(n+1);
//以i位置为结尾的最小花费
dp[0]=dp[1]=0;
//从左往右
for(int i=2;i<=n;i++)
{
dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
}
return dp[n];
}
};