斐波那契数列:
斐波那契数列递推关系式如下:
题目:求解斐波那契数列第n项?**
1. 递归方法
def Fibonacci(n):if n == 0 or n == 1:return nelse:return Fibonacci(n-1) + Fibonacci(n-2)
通过画出递归树,上述代码存在大量重复的操作。
例如,计算。
可以看到重复计算了。
2. 递归方法优化
如何减少重复计算呢?这里跟动态规划中剪枝的思想类似,构建一个DPTable,存储已计算过的项,达到利用空间换时间。
def Fibonacci(n):if n == 0 or n == 1:return ndp = [0] * (n+1) # 构造有n个元素的列表,存储已计算过的项dp[1] = 1for i in range(2, n+1):dp[i] = dp[i-1] + dp[i-2]return dp[i]
时间复杂度:,空间复杂度
。
3. 分治策略
斐波那契数列是二阶递推数列,存在一个的矩阵
,使得:
求解可得:
接下来就是求解。
指数的幂次方直接计算需要计算次乘法,通过二分法来求解,只需要计算
。
def metric_product(x, base):a = x[0][0]*base[0][0] + x[0][1]*base[1][0]b = x[0][0]*base[0][1] + x[0][1]*base[1][1]c = x[1][0]*base[0][0] + x[1][1]*base[1][0]d = x[1][0]*base[0][1] + x[1][1]*base[1][1]return [[a, b], [c, d]]def fib(self, n: int) -> int:if n == 0:return 0def metric(n):base = [[1, 1], [1, 0]]# 求 pow(base, n)if n == 1:return baseelif n % 2 == 0:half = metric(n//2)return metric_product(half, half)else:half = metric(n//2)return metric_product(metric_product(half, half), base)ans = metric(n)f_n = ans[0][1]return f_n
4. 动态规划
为了减少空间复杂度
def fib(n):a, b = 0, 1for _ in range(n):a, b = b, a + breturn a
时间复杂度, 空间复杂度
。
5. 求第n项关于10007的余数

利用余数的性质3,简化最后直接求出f(n)再算余数的复杂,同时也保证了数值不溢出。虽然python支持大数,这个方法也适用于其他语言。
def fab(n):a, b = 1, 1for _ in range(2, n):b, a = (a+b) % 10007, b % 10007return bn = int(input())ans = fab(n)print(ans % 10007)
