一、题目

二、做题思路
2.1 状态表示(核心基础)
状态表示即明确 dp 表中每个元素所代表的含义。其来源通常有三:直接依据题目要求 、结合经验对题目进行抽象、或在分析过程中提炼重复子问题 。本题中,题目已明确要求:数组下标 i 对应第 i 个泰波那契数,因此我们定义 dp[i] 表示第 i 个泰波那契数的值 。这是后续推导的基石,必须首先确定。
2.2 状态转移方程(关键难点)
状态转移方程描述了 dp[i] 与前面若干状态之间的递推关系 ,来源于题目给出的递推公式。本题直接依据泰波那契数列的定义:
dp[i] = dp[i-1] + dp[i-2] + dp[i-3](其中 i ≥ 3) 。
该方程将大问题拆解为规模更小的子问题 ,是整个动态规划过程的核心纽带。
2.3 初始化(边界防护)
初始化是为了保证填表过程中数组访问不越界 ,同时为递推提供起始条件 。由于状态转移方程需要用到前三个状态,当 i < 3 时无法通过方程计算,因此必须单独给出初始值。本题题目已明确:
dp[0] = 0,dp[1] = 1,dp[2] = 1 。
这些初始值是递推的**"种子"** ,是正确计算的必要前提。
2.4 填表顺序(递推方向)
填表顺序取决于当前状态所依赖的前驱状态 ,必须保证计算某一状态时,其所需的所有前置状态均已就绪 。本题中,dp[i] 依赖 i-1、i-2、i-3(均小于 i),因此采用 从左到右 (即下标从小到大)的顺序依次填充 dp 表,可确保每次计算时所需数据已经完备。
2.5 返回值(目标映射)
返回值即最终需要向调用者 输出的结果,由题目要求与状态表示 共同决定。本题要求返回第 n 个泰波那契数,而 dp[n] 正好表示该值,因此直接返回 dp[n] 。若 n 小于初始边界,则直接返回对应的初始值,避免越界访问。
三、代码
cpp
#include <vector>
using namespace std;
class Solution {
public:
int tribonacci(int n)
{
//3.初始化
if (n == 0) return 0;
if (n == 1 || n == 2) return 1;
vector<int> dp(n + 1);//1.状态表示,一个下标对应一个Tn元素
//3.初始化dp表
dp[0] = 0, dp[1] = 1, dp[2] = 1;
//2.状态转移方程 dpn = dpn-1 + dpn-2 + dpn-3
//4.填表顺序
for (int i = 3; i <= n; i++)
{
dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
}
//5.返回值
return dp[n];
}
};
四、流程图

五、题目

六、做题思路
6.1 状态表示(核心基础)
本题要求计算到达第 i 级台阶 的所有不同走法总数。因此定义 dp[i] 表示从地面(第 0 级)走到第 i 级台阶的方法数 。该定义直接来源于题目要求,且以位置为结尾 进行统计,是后续推导的出发点。
6.2 状态转移方程(关键难点)
小孩一次可以上 1 阶、2 阶或 3 阶 ,那么到达第 i 级台阶的最后一步 可能来自 i-1、i-2 或 i-3。由于这三种方式是互斥且完备 的,所以总方法数等于三者之和:
dp[i] = dp[i-1] + dp[i-2] + dp[i-3] (其中 i ≥ 4)。
同时,根据示例可验证初始值:dp[1]=1、dp[2]=2、dp[3]=4,与递推公式吻合。
6.3 初始化(边界防护)
递推公式依赖前三个状态,因此 i=1,2,3 必须手动赋值 :
dp[1] = 1 (仅 1 步),dp[2] = 2 (1+1 或 2),dp[3] = 4 (1+1+1、1+2、2+1、3)。
此外,题目提示结果可能很大,需对 100000007 (即 1e8+7)取模,每次相加后及时取模,防止溢出。
6.4 填表顺序(递推方向)
计算 dp[i] 必须依赖 dp[i-1]、dp[i-2]、dp[i-3],这些下标均小于 i。因此必须从左到右 (即下标从小到大)依次填充 dp 表,保证每个状态计算时,其所有前置状态均已就绪。
6.5 返回值(目标映射)
题目要求返回第 n 级台阶的走法数 ,而 dp[n] 正表示该值,因此直接返回 dp[n] 。若 n 在初始范围内(1~3),则直接返回对应的初始化值,无需进入递推循环,避免越界访问。
七、代码展示
cpp
#include <vector>
using namespace std;
class Solution {
public:
int waysToStep(int n)
{
//处理边界情况
if (n == 1) return 1;
if (n == 2) return 2;
if (n == 3) return 4;
const int Mod = 1e9 + 7;//模数
//1.创建dp表
vector<int> dp(n + 1);
//3. 初始化
dp[1] = 1, dp[2] = 2, dp[3] = 4;
//2.状态转移方程
for (int i = 4; i <= n; i++)
{
//4. 填表顺序(从左到右)
dp[i] = ((dp[i - 3] + dp[i - 2]) % Mod + dp[i - 1]) % Mod;
}
//5. 返回值
return dp[n];
}
};
八、流程图
