动态规化 - 斐波纳契级数

动态规化 - 斐波纳契级数

动态规划(dynamic programming,DP):高效求解递归问题。

递归问题通常需要多次重复求解子问题(subproblem),动态规划通过保存子问题的解(记忆,memoization)降低计算时间复杂度。

  • 递归(recursion):递归求解子问题

  • 记忆(memoization):保存子问题解

斐波纳契级数(Fibonacci Series)

Fibonacchi ( N ) = { 0 , for  n = 0 1 , for  n = 1 Fibonacchi ( N 1 ) + Fibonacchi ( N 2 ) , for  n > 1 \text{Fibonacchi}(N) = \begin{cases} 0, & \text{for } n = 0 \\ 1, & \text{for } n = 1 \\ \text{Fibonacchi}(N - 1) + \text{Fibonacchi}(N - 2), & \text{for } n > 1 \\ \end{cases}

1 递归

在这里插入图片描述
计算时间复杂度: T ( n ) = T ( n 1 ) + T ( n 2 ) + 1 = 2 n = O ( 2 n ) T(n) = T(n - 1) + T(n - 2) + 1 = 2^{n} = \mathcal{O}(2^{n})

def fibonacci_recur(n):
    """
    fibonacci series - recursion
    """
    
    if n == 0:
        return 0
    
    if n == 1:
        return 1
    
    return fibonacci_recur(n - 1) + fibonacci_recur(n - 2)
    
fibonacci_recur(8)
21

2 动态规化

时间复杂度(Time Complexity): O ( n ) \mathcal{O} (n) ;空间复杂度(Space Complexity): O ( n ) \mathcal{O} (n)

动态规化求解所需条件

  1. 重复子问题(Overlapping Sub-problems):动态规划中,子问题只求解一次,并将其保存以备将来使用;

  2. 最优子结构(Optimal Substructure):如果一个问题可以通过子问题求解,则该问题具有最优子结构。

动态规划方法(Dynamic Programming Approaches)

  • 自下而上(Bottom-Up):假设问题输入为 N N ,从最小可能输入开始求解并保存该解;

  • 自下而上(Top-Down):将问题分解为子问题,按需求解并将解保存。

import numpy as np
def fibonacci_dp(n):
    """
    fibonacci series - dynamic programming (bottom-up)
    """
    
    fibs = np.zeros(shape=(n, ))
    fibs[0] = 1
    fibs[1] = 1
    for idx in range(2, n):
        fibs[idx] = fibs[idx - 1] + fibs[idx - 2]
        
    return fibs[-1]

fibonacci_dp(8)
21.0
发布了103 篇原创文章 · 获赞 162 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/zhaoyin214/article/details/103078382