#6560. 2026/4/25/XRC笔记(递推)
2026/4/25/XRC笔记(递推)
递推问题学习笔记
📚 来源:竞赛向综合拔高2 - 章节2. 递推问题 📅 整理时间:2026年4月25日 📝 题目数量:20道
📖 目录
什么是递推
递推是指通过已知的初始条件和递推关系式,逐步推导出后续结果的算法思想。
核心公式
f(n) = g(f(n-1), f(n-2), ...)
与递归的区别
| 特点 | 递推 | 递归 |
|---|---|---|
| 方向 | 从下往上,自底向上 | 从上往下,自顶向下 |
| 效率 | 通常更高效 | 可能有重复计算 |
| 实现 | 循环实现 | 函数调用自身 |
| 空间 | 通常O(1)或O(n) | 需要栈空间 |
递推的核心思想
四步法
1. 定义状态:明确 f(n) 代表什么
2. 找出关系:推导 f(n) 与之前状态的关系
3. 确定初值:设置边界条件
4. 按序计算:从初值开始逐步推导
题目分类与详解
一、经典数列递推
📌 1. 兔子繁殖 (P4847)
问题描述:经典的斐波那契兔子繁殖问题。
递推关系:
f(n) = f(n-1) + f(n-2)
理解:
- 第n个月的兔子 = 上个月已有的兔子 + 这个月新出生的兔子
- 新出生的兔子 = 两个月前已有的兔子(它们现在可以繁殖)
代码模板:
long long fib[50];
fib[1] = 1, fib[2] = 1;
for (int i = 3; i <= n; i++) {
fib[i] = fib[i-1] + fib[i-2];
}
cout << fib[n];
难点:大数处理,注意数据范围。
📌 2. Pell数列 (P4843)
问题描述:Pell数列定义。
递推关系:
P(n) = 2 * P(n-1) + P(n-2)
P(1) = 1, P(2) = 2
与斐波那契的对比: | 数列 | 递推公式 | 特点 | |------|----------|------| | 斐波那契 | f(n) = f(n-1) + f(n-2) | 系数都为1 | | Pell | P(n) = 2*P(n-1) + P(n-2) | 系数变为2 |
代码模板:
long long pell[100];
pell[1] = 1, pell[2] = 2;
for (int i = 3; i <= n; i++) {
pell[i] = 2 * pell[i-1] + pell[i-2];
}
📌 3. 汉诺塔的移动次数 (P4846)
问题描述:计算汉诺塔问题的最少移动次数。
递推关系:
h(n) = 2 * h(n-1) + 1
h(1) = 1
推导过程:
- 把上面n-1个盘子从A移到B:h(n-1)次
- 把最大的盘子从A移到C:1次
- 把n-1个盘子从B移到C:h(n-1)次
- 总共:2*h(n-1) + 1
通项公式:
h(n) = 2^n - 1
📌 4. 输出杨辉三角的前N行 (P4849)
问题描述:输出杨辉三角。
递推关系:
C[i][j] = C[i-1][j-1] + C[i-1][j]
C[i][0] = C[i][i] = 1
特点:
- 每行首尾都是1
- 中间每个数等于上方两数之和
- 第n行有n个元素
代码模板:
int c[35][35];
for (int i = 1; i <= n; i++) {
c[i][1] = 1;
c[i][i] = 1;
for (int j = 2; j < i; j++) {
c[i][j] = c[i-1][j-1] + c[i-1][j];
}
}
二、计数类递推
📌 5. 铺地砖 (P4848) & 铺地砖-简化版 (P4858)
问题描述:用1×1、1×2、1×3的地砖铺满1×n的方格,有多少种铺法?
递推关系:
f(n) = f(n-1) + f(n-2) + f(n-3)
理解:
- 最后一块放1×1:前面有f(n-1)种
- 最后一块放1×2:前面有f(n-2)种
- 最后一块放1×3:前面有f(n-3)种
简化版:只考虑1×1和1×2两种地砖
f(n) = f(n-1) + f(n-2)
即斐波那契数列!
📌 6. 骨牌铺方格 (P4853) & 骨牌铺方格-简化版 (P4857)
问题描述:用骨牌铺满方格的方案数。
递推关系:
f(n) = f(n-1) + 2*f(n-2) // 完整版
f(n) = f(n-1) + f(n-2) // 简化版
关键理解:
- 简化版:同斐波那契
- 完整版:最后一块竖着放 + 最后两块横着放(2种方式)
📌 7. 平面分割问题 (P4852)
问题描述:n条封闭曲线把平面分割成多少区域?
递推关系:
f(n) = f(n-1) + 2*(n-1)
f(1) = 2
推导:第n条曲线与前面n-1条曲线各交于2点,每穿过一条曲线就新增2个区域。
通项公式:
f(n) = n^2 - n + 2
📌 8. 猴子吃桃问题 (P4813)
问题描述:猴子每天吃掉一半多一个,最后剩一个,求最初有多少。
递推关系(逆向思维):
f(n) = 2 * (f(n+1) + 1)
或者正向:
a[i+1] = a[i] / 2 - 1
三、二维递推/动态规划入门
📌 9. 数塔问题 (P4845) & 数塔的行走路径 (P4855)
问题描述:从塔顶走到塔底,求最大路径和。
递推关系(自底向上):
dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) + a[i][j]
关键:从下往上推,每步选更大的子路径。
求路径:需要记录选择,回溯输出。
📌 10. 摘花生问题 (P4850) & 摘花生问题2 (P4854)
问题描述:从左上角走到右下角,只能向右或向下,求最大花生数。
递推关系:
dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + a[i][j]
边界处理:
dp[1][1] = a[1][1]
dp[1][j] = dp[1][j-1] + a[1][j] // 第一行
dp[i][1] = dp[i-1][1] + a[i][1] // 第一列
📌 11. 过河卒 (P4844)
问题描述:棋盘上卒从A点到B点,避开马的控制点。
递推关系:
dp[i][j] = dp[i-1][j] + dp[i][j-1] // 如果该点可达
注意事项:
- 马的控制点要标记为不可达
- 注意边界条件
📌 12. 矩阵求和 (P4851)
问题描述:矩阵相关的递推求和问题。
思路:二维前缀和或递推累积。
📌 13. 木瓜地 (P4840)
问题描述:类似的矩阵路径问题。
四、路径计数类递推
📌 14. 走出迷宫的方法数 (P4601) & 走出迷宫的方法数2 (P4602)
问题描述:计算从起点到终点的路径数量。
递推关系:
dp[i][j] = dp[i-1][j] + dp[i][j-1] // 无障碍时
有障碍的情况:
if (grid[i][j] == 障碍) dp[i][j] = 0;
else dp[i][j] = dp[i-1][j] + dp[i][j-1];
递推解题模板
一维递推模板
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
// 1. 定义状态数组
long long f[n+1];
// 2. 确定初值
f[1] = 1;
f[2] = 2; // 根据题目确定
// 3. 递推计算
for (int i = 3; i <= n; i++) {
f[i] = f[i-1] + f[i-2]; // 递推关系
}
// 4. 输出结果
cout << f[n] << endl;
return 0;
}
二维递推模板
#include <iostream>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
// 定义状态数组
long long dp[n+1][m+1];
int a[n+1][m+1];
// 读取数据
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
// 初始化边界
dp[1][1] = a[1][1];
for (int i = 2; i <= n; i++) dp[i][1] = dp[i-1][1] + a[i][1];
for (int j = 2; j <= m; j++) dp[1][j] = dp[1][j-1] + a[1][j];
// 递推
for (int i = 2; i <= n; i++) {
for (int j = 2; j <= m; j++) {
dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + a[i][j];
}
}
cout << dp[n][m] << endl;
return 0;
}
常见错误与技巧
⚠️ 常见错误
| 错误类型 | 说明 | 解决方案 |
|---|---|---|
| 数组越界 | 访问f[0]或f[n+1] | 仔细检查边界 |
| 数据溢出 | 结果超过int范围 | 使用long long |
| 初值错误 | 边界条件设置错误 | 手动验证小数据 |
| 递推方向错误 | 自顶向下还是自底向上 | 画图分析 |
✅ 技巧总结
- 画表格推导:手工计算前几项,验证递推关系
- 找规律:从简单情况开始,逐步推广
- 逆向思维:有时候从后往前推更简单
- 空间优化:如果只需要最后结果,可以用滚动数组
练习建议
📋 推荐练习顺序
| 阶段 | 题目 | 重点 |
|---|---|---|
| 入门 | 兔子繁殖、猴子吃桃 | 理解基本递推思想 |
| 基础 | Pell数列、汉诺塔 | 掌握一维递推 |
| 进阶 | 铺地砖、骨牌铺方格 | 计数类递推 |
| 提高 | 数塔问题、摘花生 | 二维递推/DP入门 |
| 挑战 | 过河卒、走出迷宫 | 路径计数 |
📊 题目难度分布
入门 ★☆☆☆☆ : 兔子繁殖、猴子吃桃、汉诺塔
基础 ★★☆☆☆ : Pell数列、杨辉三角、平面分割
进阶 ★★★☆☆ : 铺地砖、骨牌铺方格、木瓜地
提高 ★★★★☆ : 数塔问题、摘花生、过河卒
挑战 ★★★★★ : 走出迷宫的方法数2、数塔的行走路径
📝 笔记总结
核心要点
- 递推三要素:状态定义、递推关系、初始条件
- 一维递推:注意递推方向和数据范围
- 二维递推:注意边界初始化和遍历顺序
- 计数问题:确定"最后一步"的选择方式
记忆口诀
递推问题不复杂,
状态关系要找对。
初值边界定清楚,
从小到大一步步。
🔗 相关资源
- OJ平台:bwloj.com
- 训练:竞赛向综合拔高2
- 题目编号:P4601-P4858
💡 提示:递推是动态规划的基础,掌握好递推思想对后续学习DP非常重要!