递归思想
相对于迭代,递归不需要维护许多变量,其过程更容易理解,也更容易实现。但要注意为递归函数编写终止条件,否则将产生无限递归。
一般递归求解问题需满足的条件:
(1)把要解决的问题转化为一个子问题,这个子问题规模更小、具有与原来问题相同解法。
(2)原问题可以通过子问题解决而组合解决。
(3)存在一种简单的情境,是问题在简单情境下退出。
例子:斐波拉契数列问题
一个数列满足 1,1,2,3,5…… 的形式,即当前项为前两项之和的形式,那么则称这个数列为斐波拉契数列。假设现在要求第 n 项数列的值。
f(n)由f(n-1)+f(n-2)求得,即原问题可以转化为两个子问题,满足条件一。
假设求得 f(n-1)、f(n-2)后,根据f(n)=f(n-1)+f(n-2)求得f(n), 即原问题可以通过子问题的解决而解决,满足条件二。
已知f(1)=1,f(2)=1,计算到此步,递归停止,满足条件三。
代码如下:
#递归思想
‘’’javascrip
def fab(n):
if n==1 or n==2:
return 1
else:
return fab(n-1)+fab(n-2)
for i in range(1,11):
print(fab(i), end = ' ')
#循环思想
def Fab (n):
n1 = 1
n2 = 1
n3 = 2
if n == 1:
return n1
if n == 2:
return n2
else:
for i in range(3,n+1):
n3 = n2 + n1
n1 = n2
n2 = n3
return n3
动态规划(dynamic programming)
动态规划是运筹学的一个分支,是求解决策过程最优化的数学方法。它把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解。
使用动态规划特征:
- 求一个问题的最优解
- 大问题可以分解为子问题,子问题还有重叠的更小的子问题
- 整体问题最优解取决于子问题的最优解(状态转移方程)
- 从上往下分析问题,从下往上解决问题
- 讨论底层的边界问题
动态规划图解过程见:https://www.jianshu.com/p/d6efacd8a252
例子:走楼梯问题
有十个台阶,从上往下走,一次只能走一个或两个台阶,请问总共有多少种走法?
最优子结构:我们来考虑要走到第十个台阶的最后一步,最后一步必须走到第八或者第九。不难得到 f(10) = f(9)+f(8)。f(9) = f(8)+f(7)
边界:f(1) = 1, f(2) = 2
状态转移:f(n) = f(n-1) + f(n-2)
#递归代码
def get_count(n):
if n == 1:return 1
if n == 2:return 2
else:
return get_count(n-1)+get_count(n-2)
print(get_count(10))
#备忘录算法代码:
def climb_stairs(n):
way = [0, 1, 2]
for i in range(3, n + 1):
way.append(way[i - 1] + way[i - 2])
return way[n]
回顾:
https://blog.csdn.net/weixin_44157737/article/details/85172377
https://blog.csdn.net/weixin_44157737/article/details/85070502
https://blog.csdn.net/weixin_44157737/article/details/85128531
https://blog.csdn.net/weixin_44157737/article/details/85172256