从斐波那契数列初探动态规划

Posted 光城

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从斐波那契数列初探动态规划相关的知识,希望对你有一定的参考价值。

动态规划

1.规律

  • 递归+记忆化 -> 递推(动态递推)

  • 状态的定义:opt[n],dp[n],fib[n]

  • 状态转移方程:opt[n]=best_of(opt[n-1],opt[n-2],…)

  • 最优子结构

2.斐波那契数列

2.1 递归

f(n)=f(n-1)+f(n-2)

f(0)=0

f(1)=1

1def fib(n):
2    return n if n<=1 else fib(n-1)+fib(n-2)

复杂度分析

复杂度为2^n。时间复杂度为每次节点相加,虽然并非满二叉树,但是数量级上是2^n。

2.2 记忆化

那如何加速呢?(也就是记忆化。)

记忆化就是增加了缓存,如下所示:

 1def fib1(n,memory):
2    if n<=0:
3        return 0
4    elif n==1:
5        return 1
6    elif not memory[n]:
7        memory[n]=fib1(n-1,memory)+fib1(n-2,memory)
8    return memory[n]
9n = 20
10memory = [0]*(n+1)
11print(fib1(n,memory))

这样就把时间复杂度变为O(n)。

2.3 递推

上述写得像递归又不像递归,很别扭,然后我们将递归+记忆化,得到递推。

从叶子节点顺推上去,直接递推更加容易,于是得到这种解法。

1def fib2(n,memory):
2    memory[0]=0
3    memory[1]=1
4    for i in range(n+1):
5        memory[i]=memory[i-1]+memory[i-2]
6    return memory[n]
7memory = [0]*(n+1)
8print(fib(20))
9print(fib1(n,memory))

上述递归+记忆化=>递推就是dp思想。

dp转移方程(状转移方程)就是:memory[i]=memory[i-1]+memory[i-2]。

这是一种非常简单的dp。平时要比这个复杂多。


以上是关于从斐波那契数列初探动态规划的主要内容,如果未能解决你的问题,请参考以下文章

动态规划法从斐波那契数列谈起

动态规划法从斐波那契数列谈起

算法进阶--动态规划

(转)从斐波那契数列看Java方法的调用过程

动态规划1 —— 01背包详解

动态规划1 —— 01背包详解