【动态规划】斐波那契数列模型
前言
我们将深入探讨解决斐波那契数列模型相关问题的解决方法。通过一系列精心挑选的例题,我们将展示如何运用DP的核心原则来解决各种编程挑战,从泰波那契数的计算到楼梯爬升问题,再到解码方法的多样性。每个问题都将通过状态表示、状态转移方程、初始化、填表顺序和返回值的详细分析来解构,旨在提供一个清晰的算法实现框架,帮助读者掌握DP的精髓,并在实际编程中灵活运用。
一、第 N 个泰波那契数
题目链接:第 N 个泰波那契数
泰波那契序列 Tn 定义如下:
T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn + 3 = Tn + Tn + 1 + Tn + 2
给你整数 n,请返回第 n 个泰波那契数 Tn 的值。
算法流程:
- 状态表示
由题给出的要求:返回第 n 个泰波那契数 Tn 的值,所以确定 dp[i] 表示:第 i 个泰波那契数的值
- 状态转移方程
对题中给出的递推公式:Tn+3 = Tn + Tn+1 + Tn+2,两边同时令n = n-3时,可得Tn = Tn-3 + Tn-2 + Tn-1,所以我们可以得到状态转移方程:
dp[i] = dp[i - 3] + dp[i - 2] + dp[i - 1]
- 初始化
由状态转移方程可知,数组下标不能小于0,故 i 的取值最小为 i = 3,所以我们在填表之前需要将 0,1,2 的位置值初始化。由题中给出 T0, T1, T2 的值,即可初始化:dp[0] = 0, dp[1] = dp[2] = 1
- 填表顺序
从左往右
- 返回值
要求Tn的值,应该返回 dp[n] 的值
示例代码:
int tribonacci(int n)
{
// 注意提前处理边界条件,避免访问越界
if (n == 0) {
return 0; }
if (n == 1 || n == 2) {
return 1; }
// 滚动数组节约空间
size_t a = 0, b = 1, c = 1;
size_t result = a + b + c;
for (int i = 3; i < n; ++i)
{
a = b;
b = c;
c = result;
result = a + b + c;
}
return result;
}
二、三步问题
题目链接:三步问题
有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。
实现一种方法,计算小孩有多少种上楼梯的方式。
结果可能很大,你需要对结果模1000000007。
提示:
n范围在[1, 1000000]之间
算法流程:
- 状态表示
dp[i] 表示:到达 i 位置时,一共有多少种方法
- 状态转移方程
由于 dp[i] 表示一共多少中方式可以到 i 位置,且题目规定一次可以上1,2,3个台阶,所以得到状态