跳转至

递推

✨ 什么是递推?

递推(Iteration / Dynamic Programming - Bottom-Up) 是一种通过从小到大逐步推导来解决问题的方法,与递归 自顶向下 相对,递推是 自底向上 的过程。

递推就是我们熟悉的 写一个循环来推公式,适合问题中每个状态都依赖于较小状态的情况。

本质:利用一个数组或变量,按顺序从已知初始值开始,逐步构造出目标结果。


🆚 与递归的对比

特点 递归(Recursion) 递推(Iteration)
执行方向 自顶向下 自底向上
调用结构 函数调用自身 使用循环
空间消耗 有调用栈开销 一般较少
复杂度 有时重复计算 每个子问题只算一次
易理解性 更贴合数学定义 更接近计算实现

📦 递推解题的基本步骤

  1. 明确状态表示
  2. 确定初始值(边界)
  3. 找出状态转移方程
  4. 使用 for 循环按顺序计算

🧠 示例:斐波那契数列(递推实现)

我们要求第 n 个斐波那契数:

数列定义:

\[ F(1) = 1,\quad F(2) = 1,\quad F(n) = F(n-1) + F(n-2)\quad (n \ge 3) \]

🚀 C++ 实现(数组方式)

const int N = 1e5 + 5, mod = 998244353;
int fib[N];

fib[1] = fib[2] = 1;
for (int i = 3; i <= n; i++) 
{
    fib[i] = (fib[i - 1] + fib[i - 2]) % mod;
}

🧮 空间优化(滚动数组)

int a = 1, b = 1, c;
for (int i = 3; i <= n; i++) 
{
    c = (a + b) % mod;
    a = b;
    b = c;
}

时间复杂度:$O(n)$ 空间复杂度:$O(1)$(优化后)


🧩 二维递推例子

例题1:杨辉三角

杨辉三角是组合数 $C(n, k)$ 的排列形式。

状态转移:

\[ C(n, k) = C(n-1, k-1) + C(n-1, k) \]

边界条件:

\[ C(n, 0) = C(n, n) = 1 \]

C++ 实现:

const int N = 1005, mod = 1e9 + 7;
int C[N][N];

for (int i = 0; i <= n; i++) 
{
    C[i][0] = C[i][i] = 1;
    for (int j = 1; j < i; j++)
    {
        C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) mod;
    }
}

例题2:棋盘路径数

给定一个 $n \times m$ 的棋盘,从 $(1, 1)$ 出发,每次只能向右或向下,求到达 $(n, m)$ 的路径数。

状态表示:

  • $dp[i][j]$ 表示走到格子 $(i, j)$ 的方案数

递推关系:

\[ dp[i][j] = dp[i-1][j] + dp[i][j-1] \]

走到格子 $(i,j)$ 的方案等于走到格子 $(i-1,j)$ 的方案数加上走到格子 $(i,j-1)$ 的方案数。

边界条件:

  • 第一行和第一列只有一种走法(一直向右或一直向下)

C++ 实现:

const int N = 1005, mod = 998244353;
int dp[N][N];

dp[1][1] = 1;
for (int i = 1; i <= n; i++) 
{
    for (int j = 1; j <= m; j++) 
    {
        if (i > 1) dp[i][j] += dp[i - 1][j];
        if (j > 1) dp[i][j] += dp[i][j - 1];
        dp[i][j] %= mod;
    }
}
cout << dp[n][m];

📌 说明:

  • 时间复杂度:$O(n \cdot m)$
  • 空间可以进一步滚动优化为一维数组

✅ 适合用递推的场景

  • 子问题之间无重叠计算(从前推后)
  • 问题可以明确列出状态转移公式
  • 不需要回溯路径或多分支选择

常见如:

  • 数列求值
  • 动态规划问题(线性 DP、背包、状态转移)
  • 计数类问题

💬 小结

  • 递推写法更贴近程序员的 循环 思维
  • 若状态较多或可以线性推进,优先考虑递推
  • 若问题是 分治式 的、需要 尝试所有可能 的,递归 + 回溯更适合

📌 建议同学在写完递归后,尝试转化为递推,训练 状态表达能力边界思维,为动态规划打好基础!