CC++ & Algorithm

Python递推思想

中等3
语言版本:C++Python
概述:递推就是用已知的旧结果,按照规律推出新结果,就像搭积木一样层层向上。

用“搭积木”的方法学编程:Python递推思想轻松入门

你有没有玩过搭积木?一开始只有最下面一块,然后你一层一层往上叠,每一块都稳稳地放在前面的积木上,最后就能搭成一座高塔。递推就是这种“搭积木”的思维方式——用已知的旧结果,按照固定的规律,一步步推出新的结果。在编程中,当我们遇到一串有规律的数字或状态时,只要知道第一个数(初始条件)和变化规则(递推关系式),计算机就能像自动搭积木一样,帮你算出后面的每一个数。这个方法简单又高效,是编程里非常重要的基础思想。


一、什么是递推?先从生活中的例子说起

递推的核心就三点:一个起点 + 一个规律 + 重复执行

1. 像爬楼梯一样简单

假设你每天爬楼梯回家。你家住在5楼,你从1楼开始,每次上1层台阶。那么:

  • 第1步:你在1楼(已知)
  • 规律:每次往上走1层
  • 第2步:1 + 1 = 2楼
  • 第3步:2 + 1 = 3楼
  • ……

发现了吗?你只要记住“当前在几楼”,再按规律“加1”,就能知道下一步到几楼。编程也是同样的道理。

2. 存零花钱的例子

妈妈给你一个存钱罐:第一天你放1元,之后每天比前一天多放1元。那么:

  • 第1天:1元
  • 第2天:1 + 1 = 2元
  • 第3天:2 + 1 = 3元
  • ……

规律就是“每天加1”,起点是“第1天1元”。如果你想知道第100天存了多少钱,难道要手动加100次吗?不用!用递推编程,几行代码就能算出来。

下面这个程序演示了最简单的递推:从1开始,每次加1,输出前10个数。

# 从1开始,每次加1,输出前10个数
first = 1          # 第一个数,起点
print(first)       # 先打印起点
for i in range(1, 10):
    next_number = first + 1  # 规律:加1
    print(next_number)
    first = next_number      # 把新数变成旧的,为下一次做准备

运行结果就是:1, 2, 3, 4, 5, 6, 7, 8, 9, 10。

这段代码里,变量 first 就像“当前楼层”,每次算出下一层后,就把下一层当作新的“当前楼层”,然后继续下一轮。这种“用旧变量推出新变量,再更新旧变量”的方法,就是递推的基本程序写法。


二、递推关系式:找到那把“钥匙”

递推关系式就是告诉我们“怎么从前面的结果得到后面的结果”的数学规则。它像一把钥匙,有了它,计算机才能自动计算。

1. 找规律:等差数列

观察这串数字:3, 6, 9, 12, 15, ... 你能找出规律吗?
相邻两个数的差:6-3=3,9-6=3,12-9=3,15-12=3。每次都是加3。
所以递推关系式是:第n项 = 第n-1项 + 3,初始条件:第1项=3。

写成Python代码:

# 递推关系式:第n项 = 第n-1项 + 3,初始项=3
n = 10  # 我们要算前10项
first = 3  # 初始项,第1项
print("第1项:", first)
for i in range(2, n + 1):
    next_term = first + 3   # 应用递推关系式:加3
    print(f"第{i}项:", next_term)
    first = next_term        # 更新旧值为新值

2. 找规律:平方数序列

1, 4, 9, 16, 25, ... 这个数列每一项都是 n²(第n项 = n×n)。这个规律直接用了n,没有用到前一项,所以它本身不是递推关系式(递推关系必须依赖前面的项)。不过我们也可以写出它的递推形式:观察相邻平方数的差:4-1=3,9-4=5,16-9=7,25-16=9……这些差是连续的奇数:3,5,7,9,... 所以第n项 = 第n-1项 + (2n-1)。这样就用到了前一项,变成了递推。

3. 找规律:稍微复杂的例子

数列:2, 4, 8, 16, 32, ... 这是每次乘以2。递推关系式:第n项 = 第n-1项 × 2,初始项=2。

数列:100, 90, 81, 73, 66, ... 观察:90-100=-10,81-90=-9,73-81=-8,66-73=-7……每次减的数减少1(减10、减9、减8……)。这个规律稍微复杂,但也可以写成递推关系。

新手容易犯的错误:只看到表面数字,忘了关系式必须用**前一项(或前几项)**来表达。比如数列1, 3, 5, 7, ... 如果写成“第n项 = 2n-1”就不是递推关系式(因为没有用到前一项)。正确的递推是:第n项 = 第n-1项 + 2。


三、经典递推问题:斐波那契数列(兔子数列)

递推最有名的例子就是斐波那契数列。它来自一个有趣的兔子问题:

假设一对刚出生的兔子,要过一个月才能长大,再过一个月(也就是两个月大)才能生一对小兔子。之后每个月都生一对。每次生的都是刚出生的兔子。如果不考虑死亡,问每个月一共有多少对兔子?

答案就是:第1个月1对,第2个月1对,第3个月2对,第4个月3对,第5个月5对,第6个月8对……这个数列就是:1, 1, 2, 3, 5, 8, 13, 21, ...

观察发现:从第三个月开始,每个月的兔子对数等于前两个月之和
写成递推关系式:F(n) = F(n-1) + F(n-2),初始条件:F(1)=1,F(2)=1。

用Python实现非常简洁,只需要三个变量来回更新:

# 计算斐波那契数列的前20项
a = 1  # F(1):第一个月的兔子对数
b = 1  # F(2):第二个月的兔子对数
print("第1项:", a)
print("第2项:", b)
for i in range(3, 21):
    c = a + b       # 递推关系式:F(n) = F(n-1) + F(n-2)
    print(f"第{i}项:", c)
    a, b = b, c     # 更新前两项:新的a是原来的b,新的b是新算出的c

运行结果会输出前20个斐波那契数。这段代码里:

  • a 扮演 F(n-2)
  • b 扮演 F(n-1)
  • c 就是新算出的 F(n)

更新时,a = b, b = c 相当于把整条队列往前推了一步。注意:Python的 a, b = b, c 是同时赋值,不会互相影响。

斐波那契数列不仅在数学里有趣,在自然界也到处出现:向日葵的螺旋、松果的排列、花瓣数量……很多都藏着这个数列。编程中用递推计算,比用数学公式(比如黄金分割比)更直观,而且能算到任意项(只要数字不溢出)。


四、新手最容易犯的三个错误

错误1:忘记更新旧变量

有的同学写出这样的代码:

first = 1
for i in range(1, 10):
    next_number = first + 1
    print(next_number)
    # 忘记写:first = next_number

结果会一直输出2(因为first始终是1)。一定要记得把新值赋给旧变量,否则永远在原地踏步。

错误2:初始条件弄错

比如斐波那契数列,如果初始条件写成F(1)=0, F(2)=1,就会得到0,1,1,2,3,... 和经典结果不同。每个递推问题都要仔细核对起点是否正确。

错误3:递推关系式写错

比如把加3写成了加2。建议先手动算两个例子验证一下。比如算完前3项,看是否和题目一样。


五、完整可运行示例:用递推算零花钱

下面是一个“存零花钱”的完整程序:第一天存1元,以后每天比前一天多存1元。请计算并输出前10天每天存了多少钱,以及一共存了多少。

# 存零花钱:第一天1元,以后每天比前一天多存1元
# 输入:要计算的天数
# 输出:每天存的钱和总钱数

days = 10  # 要计算多少天
today_money = 1  # 第一天存的钱,也是当前这一天的钱
total = 0        # 总钱数,初始为0

print("天数 | 当天存的钱 | 总共的钱")
print("-----------------------------")
for day in range(1, days + 1):
    print(f"第{day:2d}天 |   {today_money:2d}元      |   {total + today_money:3d}元")
    total = total + today_money   # 把今天的钱加入总金额
    today_money = today_money + 1 # 明天的钱比今天多1元(递推关系式)

运行结果:

天数 | 当天存的钱 | 总共的钱
-----------------------------
第 1天 |    1元      |     1元
第 2天 |    2元      |     3元
第 3天 |    3元      |     6元
第 4天 |    4元      |    10元
第 5天 |    5元      |    15元
第 6天 |    6元      |    21元
第 7天 |    7元      |    28元
第 8天 |    8元      |    36元
第 9天 |    9元      |    45元
第10天 |   10元      |    55元

这个程序既展示了递推的“每天更新当天钱数”,也展示了“累加”的递推(总钱数每次加上今天钱数)。如果你想知道第100天存了多少,只需把 days = 10 改成 days = 100,计算机瞬间就算出来了。


六、总结与拓展

递推的核心就是从已知出发,按固定规律反复计算。它特别适合处理有规律、有顺序的数据。生活中的例子比比皆是:每天背单词数量、爬楼梯步数、存钱计划、细胞分裂数量……只要你找到了“起点”和“怎么变”,就能用递推来编程。

相关知识点指引:

  • 递归:和递推很像,但递归是“从后往前”调用自己,而递推是“从前往后”循环计算。递归代码更简洁,但容易栈溢出;递推更高效,适合大规模计算。
  • 动态规划:递推是动态规划的基础,很多算法题(如背包问题、最短路径)都要先找到递推关系式。
  • 数学归纳法:递推的数学基础,就是“已知第一个成立,假设第k个成立,证明第k+1个成立”。

如果你掌握了递推,就拿到了编程世界里一把非常实用的钥匙。下次遇到类似“第一天……之后每天都……”的问题,试着用递推来写程序吧!

例题精讲

1单选题

以下哪一项正确描述了斐波那契数列的递推关系?

AF(n) = F(n-1) + 1
BF(n) = F(n-1) + F(n-2)
CF(n) = F(n-1) * F(n-2)
DF(n) = F(n-1) - F(n-2)
2判断题

递推算法在求解问题时,必须明确初始条件(边界值)。

3填空题
请补全以下代码,用递推(迭代)方式计算斐波那契数列第n项(n≥1)。
def fib(n):
    if n <= 2:
        return 1
    a, b = 1, 1
    for _ in range(3, n+1):
        a, b = b, ___
    return b
4判断题

递推算法(迭代)通常比递归算法在解决相同问题时效率更高,因为它避免了重复计算和函数调用开销。

5单选题

以下哪个问题最不适合使用递推思想直接求解?

A计算1+2+3+...+n的和
B生成杨辉三角的某一行
C使用递归方式求解汉诺塔问题
D求第n个斐波那契数