解锁动态规划:从斐波那契到高效算法

这篇具有很好参考价值的文章主要介绍了解锁动态规划:从斐波那契到高效算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

👤作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。
会一些的技术:数据分析、算法、SQL、大数据相关、python

欢迎加入社区:码上找工作
作者专栏每日更新:

LeetCode解锁1000题: 打怪升级之旅
python数据分析可视化:企业实战案例
备注说明:方便大家阅读,统一使用python,带必要注释,公众号 数据分析螺丝钉 一起打怪升级

动态规划(Dynamic Programming, DP)是解决优化问题的一种算法策略,它将一个复杂问题分解为更小的子问题,通过解决子问题来逐步找到复杂问题的最优解。动态规划适用于有重叠子问题和最优子结构性质的问题。接下来,我们通过一个经典的动态规划问题——斐波那契数列(Fibonacci Sequence)来详细介绍动态规划的思路和实现步骤。

问题定义

斐波那契数列是这样一个序列:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …,其中每个数字(从第三个数字起)都是前两个数字的和。斐波那契数列的定义如下:

解锁动态规划:从斐波那契到高效算法,LeetCode解锁1000题: 打怪升级之旅,动态规划,算法,leetcode,python,数据结构

我们的目标是编写一个函数,输入n,输出斐波那契数列的第n项。

1. 递归解法(非DP解)

首先,我们尝试使用递归解法,这种方法简单直观,但效率较低。

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

这个递归解法虽然简单,但它进行了大量重复计算,时间复杂度为O(2^n)。 

我们可以通过分析斐波那契数列的递归树来直观地看出重复计算的发生。

斐波那契数列的递归树

考虑计算F(5)的过程,递归树如下所示:

在这个树状结构中,每个节点表示一个递归调用,节点的值是调用的参数。从这个树中我们可以观察到:

  1. 重复的子问题F(3)F(2)F(1)F(0)被计算了多次。特别是F(2),在整个计算过程中被重复计算了三次。

  2. 增长的递归调用:随着参数n的增加,递归调用的数量呈指数级增长。例如,F(n)的计算会导致F(n-1)F(n-2)的计算,而这些调用又会分别导致更多的递归调用。

分析重复计算的原因

重复计算的主要原因在于,递归解法中对每个子问题的解决都是独立进行的,它没有考虑到在求解过程中,很多子问题实际上是相同的。由于递归方法没有记录已经解决的子问题的结果,每次遇到这些子问题时,它都会重新进行计算。

2. 动态规划解法

为了提高效率,我们使用动态规划的方法,避免重复计算。

步骤1:定义状态

定义dp数组,其中dp[i]表示斐波那契数列中第i个数的值。

步骤2:确定状态转移方程

根据斐波那契数列的定义,我们可以得到状态转移方程:dp[i] = dp[i-1] + dp[i-2]

步骤3:确定初始条件和边界条件

dp[0] = 0, dp[1] = 1

步骤4:计算顺序

从小到大计算dp数组的值。

动态规划代码实现
def fibonacci_dp(n):
    if n <= 1:
        return n
    dp = [0] * (n+1)
    dp[1] = 1
    for i in range(2, n+1):
        dp[i] = dp[i-1] + dp[i-2]
    return dp[n]

这种方法的时间复杂度为O(n),空间复杂度也为O(n)。

3. 动态规划优化

对于斐波那契数列问题,我们实际上不需要保存整个dp数组,只需要保存前两个状态即可。

优化后的代码
def fibonacci_dp_optimized(n):
    if n <= 1:
        return n
    prev, curr = 0, 1
    for i in range(2, n+1):
        prev, curr = curr, prev + curr
    return curr

这个优化后的版本将空间复杂度降低到了O(1)。

4. 算法思考

1. 子问题

在动态规划中,我们将原问题分解为较小的、相互关联的子问题。对于斐波那契数列问题,求F(n)可以看作是一个原问题,它可以分解为求F(n-1)F(n-2)两个子问题。而F(n-1)F(n-2)又可以继续分解,直到F(1)F(0)

2. 重叠子问题

动态规划适用于那些有大量重叠子问题的情况,即不同的问题求解路径中包含了许多相同的子问题。在递归求解斐波那契数列时,F(n-1)F(n-2)会重复计算F(n-3)F(n-4)等更小的子问题。动态规划通过记忆化(存储)这些子问题的解来避免重复计算。

3. 最优子结构

斐波那契数列问题具有最优子结构的特点,即问题的最优解包含了其子问题的最优解。虽然斐波那契数列问题本身不涉及“最优化”,但其解决方法体现了最优子结构的思想:F(n)的最优解(即准确解)可以通过组合F(n-1)F(n-2)的解得到。

4. 动态规划表(DP Table)

在这个例子中,dp数组就是所谓的动态规划表。它用来记录每一步的结果(即每个F(i)的值),以便于后续的计算可以直接引用前面的结果,而不是重新计算。这种方法极大地提高了效率,因为每个子问题只被解决一次,并且一旦被解决,其结果就会被保存。

5. 状态转移方程

动态规划的核心是状态转移方程。在斐波那契数列的例子中,状态转移方程是dp[i] = dp[i-1] + dp[i-2]。这个方程描述了问题状态之间的关系,即如何从已知的子问题的解得到当前问题的解。

通过这个斐波那契数列的例子,你可以看到,尽管我们使用的是简单的数组来存储每一步的结果,但这个过程完全体现了动态规划的思想:分解问题、解决子问题、存储子问题的解以避免重复计算。这就是dp数组与动态规划思想关联的方式,它是实现动态规划策略的一个工具。

总结

动态规划中的应用体现了动态规划的核心思想:存储中间结果,避免重复计算。这里的dp数组正是用来存储每个子问题的解,即斐波那契数列中每个位置的数值。让我们更深入地理解它与动态规划思想的关联:文章来源地址https://www.toymoban.com/news/detail-852633.html

到了这里,关于解锁动态规划:从斐波那契到高效算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 动态规划02-斐波那契类型二

    给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你计算并返回达到楼梯顶部的最低花费。 真题点击此处:746.使用最小花费爬楼

    2024年01月16日
    浏览(40)
  • LeetCode 509 斐波那契数(动态规划)

     509. 斐波那契数 - 力扣(LeetCode)   斐波那契数  (通常用  F(n)  表示)形成的序列称为  斐波那契数列  。该数列由  0  和  1  开始,后面的每一项数字都是前面两项数字的和。也就是: 给定  n  ,请计算  F(n)  。 【思路】动态规划 动规五部曲: 1.确定dp数组以及下

    2024年02月07日
    浏览(56)
  • 【算法学习】斐波那契数列模型-动态规划

            我在算法学习过程中,针对斐波那契数列模型的动态规划的例题进行了一个整理,并且根据标准且可靠一点的动态规划解题思路进行求解类似的动归问题,来达到学习和今后复习的必要。         所谓的斐波那契数列模型,即当前状态的值等于前两种状态的值之和。

    2024年02月04日
    浏览(56)
  • 动态规划之 509斐波那契数(第1道)

    题目: 斐波那契数 (通常用  表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: , ,其中 n 1 给定 n ,请计算 。 题目链接:509. 斐波那契数 - 力扣(LeetCode) 示例: 解法:

    2024年02月12日
    浏览(59)
  • 算法:动态规划---斐波那契和最短路径

    从本篇开始总结的是动态规划的一些内容,动态规划是算法中非常重要的一个版块,因此也是学习算法中的一个重点,在学习动态规划前应当要把动态规划的基础知识学习一下 动态规划既然是一个新的算法,这个名字也是新名字,那么就要首先明确这个算法的名字代表什么含

    2024年01月25日
    浏览(57)
  • 【动态规划专栏】专题一:斐波那契数列模型--------1.第N个泰波那契数

    本专栏内容为:算法学习专栏,分为优选算法专栏,贪心算法专栏,动态规划专栏以及递归,搜索与回溯算法专栏四部分。 通过本专栏的深入学习,你可以了解并掌握算法。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:动态规划专栏 🚚代码仓库:小小unicorn的代码仓库🚚

    2024年02月21日
    浏览(43)
  • 【算法优选】 动态规划之斐波那契数列模型

    动态规划相关题目都可以参考以下五个步骤进行解答: 状态表⽰ 状态转移⽅程 初始化 填表顺序 返回值 后面题的解答思路也将按照这五个步骤进行讲解。 泰波那契序列 Tn 定义如下: T0 = 0, T1 = 1, T2 = 1, 且在 n = 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2 给你整数 n,请返回第 n 个泰波那契

    2024年02月05日
    浏览(56)
  • C++算法 —— 动态规划(1)斐波那契数列模型

    每一种算法都最好看完第一篇再去找要看的博客,因为这样会帮你梳理好思路,看接下来的博客也就更轻松了。当然,我也会尽量在写每一篇时都可以让不懂这个算法的人也能边看边理解。 动规的思路有五个步骤,且最好画图来理解细节,不要怕麻烦。当你开始画图,仔细阅

    2024年02月10日
    浏览(46)
  • 动态规划入门篇——斐波那契数列与爬楼梯问题

           动态规划(Dynamic Programming,简称DP)是运筹学的一个分支,也是求解多阶段决策过程最优化问题的一种方法。它主要用来解决一类最优化问题,通过将复杂问题分解成若干个子问题,并综合子问题的最优解来得到原问题的最优解。动态规划的核心在于对问题的状态进

    2024年03月14日
    浏览(43)
  • 动态规划入门:斐波那契数列模型以及多状态(C++)

        动态规划(Dynamic programming,简称 DP)是一种解决多阶段决策问题的算法思想。它将问题分解为多个阶段,并通过保存中间结果来避免重复计算,从而提高效率。 动态规划的解题步骤一般分为以下几步: 思考状态表示,创建dp表(重点) 分析出状态转移方程(重点) 初始化 确定

    2024年02月11日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包