C++递推

🌱 一、认识递推思想

1. 什么是递推?

用生活化语言解释:

"递推就像搭积木,第一个积木放好了,第二个就按规则放,第三个也一样......一个一个地推下去。"

2. 递推和递归的区别

  • 递推是从前往后推(通常是循环实现);
  • 递归是函数自己调用自己,适合更深一点再讲。

可以打比方:

"递推像爬楼梯,每一步都知道怎么走;递归像走迷宫,需要回头找路。"


🧩 二、课程结构设计

第一课:递推的概念与"斐波那契数列"

  • 故事导入:兔子繁殖问题
  • 讲解规则:f(n) = f(n-1) + f(n-2)
  • 展示代码(用C++、Python或伪代码均可)
  • 画图辅助:用表格或柱状图展示数列

第二课:用数组进行递推

  • 引入数组:f[0] = 0; f[1] = 1;
  • 写出 for 循环实现斐波那契
  • 强调初始化的重要性

第三课:常见递推问题

类型一:爬楼梯问题
  • 每次可以爬1步或2步,有几种爬法?
  • f(n) = f(n-1) + f(n-2)
类型二:走格子问题
  • 从(0,0)走到(m,n)只能向右或向下,有几种走法?
  • 讲解二维递推 f[i][j] = f[i-1][j] + f[i][j-1]

🔍 三、教学技巧与建议

1. 用图讲解

  • 每个状态画出来,用箭头表示状态转移
  • 可以让学生贴便利贴模拟递推过程

2. 强调"初始条件"

  • 就像解数学题要给"已知"
  • 如果初始条件错了,后面就全错

3. 布置练习题(逐步递进)

  • 简单数列:斐波那契、等差、等比
  • 应用题:楼梯、走格子、换零钱、跳石头等
  • 上NOIP真题(如历年普及组一二题)

💡 四、推荐递推题目(适合入门)

题目名称 题目类型 来源/备注
斐波那契数列 一维递推 标准起点
青蛙跳台阶 一维递推 每次跳1或2步
走迷宫 二维递推 DP入门
数塔问题 从下往上递推 动态规划铺垫
摆花问题 一维+限制递推 有约束条件的递推练习

🎓 信息学奥赛·递推第一课:神奇的兔子家族


🧭 一、教学导语(适合讲课开头使用)

👩‍🏫(老师可以这样说):


同学们,今天我们来讲一个非常有趣的数学故事,叫做"兔子家族"。

古时候,有一位意大利数学家斐波那契,他思考了一个问题:

"如果有一对兔子,从出生开始需要两个月长大,从第3个月起,它们每个月都会生一对新兔子。所有新出生的兔子也会按同样的规律长大并生兔子。那一年以后,会有多少对兔子呢?"

这个问题非常有趣,因为它藏着一种叫"递推 "的思维方式------通过前面的信息,一步步推出后面的答案。


✅ 关键词解释:

  • 从第3个月起,每个月生兔子(注意:不是每两个月生一次!)
  • 所有兔子都遵守同样的生育规律
  • 递推:用前面的答案推算后面的结果

✏️ 二、第一课开头内容设计


📌 1. 目标导入(板书建议)

课题 :递推第一课------斐波那契与兔子问题
本课目标

  • 理解什么是"递推"
  • 学会用递推方法解决兔子问题
  • 学习斐波那契数列的基本形式

🐇 2. 逐月分析(配合板书或幻灯片)

引导学生逐月思考并记录兔子对数变化(可画表格或图):

月份 兔子对数(总数) 新出生兔子对数 说明
1 1 0 刚出生,还不能生
2 1 0 还在成长
3 2 1 第一对兔子长大,开始生一对新兔子
4 3 1 第一对兔子继续生
5 5 2 第一、第二个月的兔子都能生
6 8 3 第3月出生的兔子也长大了开始生

🧠 引导提问

  • "你能看出什么规律吗?"
  • "每个月的兔子数量,和前几个月有什么关系?"

📌 3. 引出递推公式(板书)

从第3个月开始,每个月兔子数量 = 前一个月 + 前两个月

板书公式:

scss 复制代码
复制编辑
f(n) = f(n - 1) + f(n - 2)
f(1) = 1
f(2) = 1

🎯 4. 小结

今天我们通过兔子的故事,了解了一种特殊的规律叫做"递推",也叫"斐波那契数列"。这个规律会在我们后面很多信息学奥赛的题目中反复出现。只要掌握了它,很多看似复杂的问题都能迎刃而解。

🧠 信息学奥赛 · 递推第二课:用数组实现斐波那契数列


🧭 一、教学导语(课堂开场白)

👩‍🏫(老师讲):


同学们,上一节我们通过兔子的故事,了解了"递推"的概念,还认识了斐波那契数列。

但在信息学比赛中,我们不能靠一张嘴去推兔子数,要靠代码来帮我们推!

今天我们要学习如何用数组和 for 循环来写出这个数列,并且要特别注意"初始化"这一关键步骤。


✏️ 二、知识目标

  • 理解为什么用数组存储每个月的兔子对数;
  • 能用 for 循环实现递推过程;
  • 掌握递推程序中的初始化技巧和重要性。

🧩 三、递推的代码实现(逐步讲解)

✅ 1. 斐波那契数列的数学公式复习

scss 复制代码
复制编辑
f(0) = 0
f(1) = 1
f(n) = f(n - 1) + f(n - 2)   (n ≥ 2)

✅ 2. 引入数组思想(板书 or PPT)

  • 我们希望记录每个月的兔子数量
  • 每一项都依赖前两项,用一个数组 f[] 来保存:
arduino 复制代码
cpp
复制编辑
int f[20];  // 开一个数组,记录前20个月的兔子数量

✅ 3. 强调初始化的重要性

ini 复制代码
cpp
复制编辑
f[0] = 0;
f[1] = 1;

🔴 讲解重点

如果没有这两个初始值,f[2] = f[1] + f[0] 就无法正确计算,程序会用"未定义"的数去递推,结果肯定错。


✅ 4. 完整代码示例(适合板书讲解)

ini 复制代码
cpp
复制编辑
#include <iostream>
using namespace std;

int main() {
    int f[20];
    f[0] = 0;
    f[1] = 1;

    for (int i = 2; i < 20; i++) {
        f[i] = f[i - 1] + f[i - 2];
    }

    for (int i = 0; i < 20; i++) {
        cout << "f[" << i << "] = " << f[i] << endl;
    }

    return 0;
}

🚨 四、易错提醒

错误类型 说明
忘记初始化 没写 f[0] = 0; f[1] = 1; 会导致程序输出错误
数组越界 例如访问 f[-1]f[20] 等非法下标
写错递推公式 比如写成 f[i] = f[i - 2] + f[i - 3]
错误循环起点 正确是 i = 2 开始(前两个数已经给定了)

🧠 五、课堂练习建议

✅ 基础练习

  • 输出前 20 项的斐波那契数列

✅ 提升练习

  • 输入一个整数 n,输出 f[n]
  • 求第 n 项的值是否为偶数
  • 统计前 20 项中,值大于 100 的有多少个

🎯 六、小结板书参考

scss 复制代码
复制编辑
★ 递推公式: f(n) = f(n-1) + f(n-2)
★ 初始化非常重要: f[0] = 0, f[1] = 1
★ 使用 for 循环从第2项开始
★ 数组 f[] 用来保存每个月的兔子对数

🧠 信息学奥赛 · 递推第三课:常见递推模型


🧭 一、教学导语

👩‍🏫(老师开场白):


同学们,前两节课我们学习了兔子问题和数组递推,也认识了斐波那契数列。

今天我们要学习两种常见的递推模型,它们在信息学比赛中经常出现:

  • 第一个是"爬楼梯"问题;
  • 第二个是"走格子"问题。

虽然表面看起来像生活小故事,但它们的本质就是递推!


🎯 二、学习目标

  • 掌握两个经典递推模型:爬楼梯、一维 → 走格子、二维;
  • 能正确列出递推公式;
  • 会用一维和二维数组进行代码实现。

🪜 三、类型一:爬楼梯问题(一维递推)

✅ 问题描述:

有一个楼梯有 n 级,每次可以爬1级或2级,一共有多少种爬法?


✅ 分析思路:

  • 如果站在第 n 级,可能来自:

    • n-1 级再爬1步;
    • n-2 级再爬2步。

🧠 所以:

scss 复制代码
复制编辑
f(n) = f(n-1) + f(n-2)

初始条件:

scss 复制代码
复制编辑
f(0) = 1  (不爬楼梯也算一种)
f(1) = 1

✅ 示例代码:

ini 复制代码
cpp
复制编辑
int f[50];
f[0] = 1;
f[1] = 1;

for (int i = 2; i <= n; i++) {
    f[i] = f[i - 1] + f[i - 2];
}
cout << "总共爬法:" << f[n];

🧱 四、类型二:走格子问题(二维递推)

✅ 问题描述:

在一个 m × n 的格子地图中,从左上角 (0,0) 走到右下角 (m,n),只能向 或向,有多少种走法?


✅ 分析思路:

  • 到达 (i, j) 的方法数 = 从上面 (i-1, j) 走一步 + 从左边 (i, j-1) 走一步

🧠 所以:

css 复制代码
复制编辑
f[i][j] = f[i-1][j] + f[i][j-1]

初始条件:

  • f[0][j] = 1 (第一行只能从左边一直走)
  • f[i][0] = 1 (第一列只能从上面一直走)

✅ 示例代码:

ini 复制代码
cpp
复制编辑
int f[20][20];

for (int i = 0; i <= m; i++) f[i][0] = 1;
for (int j = 0; j <= n; j++) f[0][j] = 1;

for (int i = 1; i <= m; i++) {
    for (int j = 1; j <= n; j++) {
        f[i][j] = f[i-1][j] + f[i][j-1];
    }
}

cout << "总共走法:" << f[m][n];

📊 五、课堂练习建议

✅ 基础题:

  • 爬 10 层台阶有几种爬法?
  • 在 4×4 的格子里有多少种走法?

✅ 提高题:

  • 限制只能向下/右走,但不能经过某个障碍格子
  • 楼梯只能以 "1步或3步" 爬法来爬,递推公式怎么变?

🧠 六、小结板书建议

scss 复制代码
复制编辑
【递推模型一】爬楼梯:
f(n) = f(n-1) + f(n-2)

【递推模型二】走格子:
f[i][j] = f[i-1][j] + f[i][j-1]

初始化:
f[0] = 1, f[1] = 1
f[0][j] = 1, f[i][0] = 1

📌 教学建议

  • 可以让学生在黑板上"走楼梯"、"走格子"做真人模拟;
  • 把问题图像化,画格子、楼梯,用箭头帮助理解递推方向;
  • 引导学生发现递推模型之间的共通性:当前位置由"上一步"或"上两步"推出。

🧩 问题再说一遍:

一个楼梯有 n 级台阶,每次你可以爬 1级2级,问:从第0级开始,爬到第n级,一共有多少种不同的走法?


🎯 举个例子来说明

比如:楼梯有3级(n = 3)

我们来找出所有的走法:

  1. 1 + 1 + 1(每次都爬一级)
  2. 1 + 2(先爬一级,再爬两级)
  3. 2 + 1(先爬两级,再爬一级)

所以总共有 3种走法


🔁 递推思想怎么来?

我们来想一个通用的逻辑:

如果我现在在第 n 级台阶,那么我最后一步可能是:

  • n-1 级走一级上来(那之前需要走到 n-1
  • 或者从 n-2 级走两级上来(那之前需要走到 n-2

这意味着:

走到第 n 级的走法数 = 走到第 n-1 级的走法数 + 走到第 n-2 级的走法数

这就是:

scss 复制代码
text
复制编辑
f(n) = f(n - 1) + f(n - 2)

是不是跟斐波那契数列一样?没错,它其实就是一个斐波那契问题的变种!


🟡 初始值该是多少?

为了让这个"加法"有开始,我们必须给出前两个台阶的"走法数":

  • f(0) = 1(不爬也是一种方案)
  • f(1) = 1(只能一步爬上去)

✅ 总结一下

台阶数 n 走法数 f(n) 说明
0 1 什么都不做
1 1 只能一步
2 2 (1+1) 或 (2)
3 3 (1+1+1), (1+2), (2+1)
4 5 用公式 f(4) = f(3)+f(2)=3+2

💡 用代码写出来:

ini 复制代码
cpp
复制编辑
int f[100];
f[0] = 1;
f[1] = 1;

for (int i = 2; i <= n; i++) {
    f[i] = f[i - 1] + f[i - 2];
}

🚸 少儿课堂小技巧

你可以用"跳格子"的游戏方式来带孩子理解:

在黑板上画一排格子(比如4格):

css 复制代码
css
复制编辑
[0]→[1]→[2]→[3]→[4]

孩子每次可以:

  • 从一个格子跳到右边1格,或者
  • 跳到右边2格

然后你问他:从0跳到4,一共有几种跳法?让他们自己试着跳,再和公式结果比对,就很容易理解了!

🧩 问题描述:骨牌覆盖问题(又叫 2×n 方格骨牌覆盖)

有一个 2×n 的方格,要用 2×1 的骨牌完全铺满。问一共有多少种不同的铺法?(骨牌可以横着或竖着放)


🧠 举例理解

例子:2×1

只能竖着放一个骨牌 → 只有 1 种方法

例子:2×2

  • 竖着放两个骨牌
  • 横着放两个骨牌

→ 总共 2 种方法

例子:2×3

可以分成两种情况考虑最后一块骨牌的放法:

  1. 最后一列是一个竖着的骨牌 → 剩下的是 2×2 → f(2)
  2. 最后两列是两个横着的骨牌 → 剩下的是 2×1 → f(1)

所以:

scss 复制代码
复制编辑
f(3) = f(2) + f(1)

✅ 递推公式总结:

scss 复制代码
复制编辑
f(n) = f(n-1) + f(n-2)
  • f(n-1):最后放一个竖着的骨牌,占用一列
  • f(n-2):最后放两个横着的骨牌,占用两列

🟢 初始值:

scss 复制代码
cpp
复制编辑
f(0) = 1   // 空格子也算一种铺法
f(1) = 1   // 一列只能竖着放一个

✅ 示例代码(C++):

ini 复制代码
cpp
复制编辑
int f[100];
f[0] = 1;
f[1] = 1;

for (int i = 2; i <= n; i++) {
    f[i] = f[i - 1] + f[i - 2];
}
cout << "铺法种数:" << f[n];

🎓 教学建议(适合小学高年级或初一学生):

  • 用磁力贴或拼图块拼一个 2×n 的格子;
  • 让孩子动手摆出几种覆盖方法(用多米诺骨牌也可以);
  • 引导他们从"最后一块骨牌"的角度思考递推;
  • 和"爬楼梯问题"进行类比 → 他们本质上是一样的模型!

🔁 总结对比三大递推模型:

问题 模型公式 本质逻辑
爬楼梯 f(n) = f(n-1) + f(n-2) 一步 or 两步
骨牌覆盖 f(n) = f(n-1) + f(n-2) 竖放 or 横放两块
斐波那契 f(n) = f(n-1) + f(n-2) 第 n 项 = 前两项之和
相关推荐
芜湖xin21 分钟前
【题解-洛谷】B4278 [蓝桥杯青少年组国赛 2023] 简单算术题
算法·
理智的灰太狼22 分钟前
题目 3298: 蓝桥杯2024年第十五届决赛真题-兔子集结
算法·职场和发展·蓝桥杯
kingmax542120084 小时前
【洛谷P9303题解】AC- [CCC 2023 J5] CCC Word Hunt
数据结构·c++·算法·广度优先
白熊1884 小时前
【机器学习基础】机器学习入门核心算法:XGBoost 和 LightGBM
人工智能·算法·机器学习
bai_lan_ya4 小时前
数据结构-排序-排序的七种算法(2)
数据结构·算法·排序算法
全域智图6 小时前
元胞自动机(Cellular Automata, CA)
人工智能·算法·机器学习
珂朵莉MM6 小时前
2022 RoboCom 世界机器人开发者大赛-本科组(省赛)解题报告 | 珂学家
人工智能·算法·职场和发展·深度优先·图论
独家回忆3646 小时前
每日算法-250601
数据结构·算法
YONYON-R&D6 小时前
DEEPSEEK帮写的STM32消息流函数,直接可用.已经测试
算法·消息流
Steve lu8 小时前
回归任务损失函数对比曲线
人工智能·pytorch·深度学习·神经网络·算法·回归·原力计划