当前位置: 首页 > news >正文

简单理解动态规划

动态规划的核心思想就一句: 将问题拆分成更小的子问题并存储结果来避免重复计算。 也就是用空间换时间

从最经典的斐波那契数列来看动态规划:

斐波那契数列:从0和1开始,后续的每一项都是前两项的和

根据斐波那契数列的概念,直觉是可以通过递归得到计算结果

function fibonacci(n) {if (n <= 1) return n;return fibonacci(n - 1) + fibonacci(n - 2);
}

我们按步骤分析代码执行顺序:


调用 fibonacci(4)fibonacci(3) + fibonacci(2)
调用 fibonacci(3)fibonacci(2) + fibonacci(1)
调用 fibonacci(2)fibonacci(1) + fibonacci(0)
fibonacci(1) 返回 1
fibonacci(0) 返回 0
所以 fibonacci(2) 返回 1
回到 fibonacci(3)fibonacci(3) = fibonacci(2) + fibonacci(1)
= 1 + 1 = 2
回到 fibonacci(4):现在计算 fibonacci(2)(这是之前的结果,我们需要再次计算):
→ fibonacci(1) + fibonacci(0)
fibonacci(1) 返回 1
fibonacci(0) 返回 0
所以 fibonacci(2) 返回 1。
最后,合并结果:fibonacci(4) = fibonacci(3) + fibonacci(2)
= 2 + 1 = 3
因此,调用 fibonacci(4) 返回 3

该算法的时间复杂度为O(2^n),耗费的时间极长,我们分析代码可以发现,递归过程中,其中许多值(如 fibonacci(2))被多次计算,我们把计算过程产生的结果存储起来,不就可以提高我们算法的效率吗!

优化后的代码如下:

function fibonacci(n) {if (n < 2) {return n}const prev = [0, 1]for (let i = 2; i <= n; i++) {prev[0] = prev[1]prev[1] = prev[0] + prev[1]}return prev[1]
}

我们只需要把数列的最后两个值存储起来,避免不必要的计算,就可以把时间复杂度降低到O(n),这个就是动态规划的核心思想。

但并不是所有问题都适合动态规划,判断一个问题是否适合使用动态规划解决,通常可以沿着以下几个步骤进行分析:

  1. 是否可以分解成子问题?子问题是否重复出现
  2. 最优解是否依赖于子问题的最优解
  3. 怎么定义问题的解决步骤
  4. 确定边界条件
  5. 分析问题的规模,以确保通过动态规划可以在合理的时间内解决它。

http://www.mrgr.cn/news/44529.html

相关文章:

  • 基于ssm 和uniapp 开发的微信小程序的学生选课系统设计与实现
  • 代码随想录 103. 水流问题
  • 开发自定义starter
  • 【电力系统】基于MATLAB的储能辅助电力系统调峰的容量需求研究
  • Flutter平台嵌入器
  • 图解Linux文件属性与目录配置
  • Ubuntu查看磁盘空间使用情况
  • 中国书法-孙溟㠭浅析碑帖《九成宫醴泉铭》
  • 分层解耦-01.三层架构
  • Stable Diffusion绘画 | 插件-Deforum:商业LOGO广告视频
  • 图像转3D视差视频:DepthFlow、kling
  • 如何搭建基于大模型的智能知识库
  • 设计模式~~~
  • 基于Netty框架的云快充协议+桩直连协议+充电桩系统
  • 【SQL】深入理解SQL:从基础概念到常用命令
  • 【机器学习-无监督学习】概率图模型
  • 油卡回收源码含教程
  • 我们如何构建 ClickHouse 内部的数据仓库【Part1】
  • openpnp - juki吸嘴尺寸
  • SpringBoot实战:旅游管理系统的设计与开发