news 2026/4/16 13:14:42

一维动态规划 - 从递归/记忆化搜索入手动态规划

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一维动态规划 - 从递归/记忆化搜索入手动态规划

从递归/记忆化搜索入手动态规划

在入门动态规划时,记忆化搜索往往比递推形式更容易想。可以先写出记忆化搜索,再转为递推形式。

记忆化搜索很好用,但并不是万能的,某些题目只有写成递推,才能结合数据结构等来优化时间复杂度,多数题目还可以优化空间复杂度。

力扣 509. 斐波那契数
洛谷 P1048 「NOIP 2005 普及组」 采药
下面以斐波那契为例:

暴力搜索

很容易实现这样一个朴素的搜索做法:

publicstaticintf1(inti){if(i==0){return0;}if(i==1){return1;}returnf1(i-1)+f1(i-2);}

时间复杂度:O ( 2 n ) O(2^n)O(2n)。搜索树可以近似为一棵二叉树,树高为 n,节点个数为O ( 2 n ) O(2^n)O(2n)
空间复杂度:O ( n ) O(n)O(n)。递归需要O ( n ) O(n)O(n)的栈空间。

这种做法的时间复杂度是指数级别的,不是我们希望的。

记忆化搜索

上面的做法为什么效率低下呢?因为同一个状态会被访问多次。

记忆化搜索是一种通过记录已经遍历过的状态的信息,从而避免对同一状态重复遍历的搜索实现方式。

这充分利用了动态规划中很多问题具有大量重叠子问题的特点,属于用空间换时间的「记忆化」思想。

// memo 为记忆化数组,初始化为 -1publicstaticintf2(inti,int[]memo){if(i==0){return0;}if(i==1){return1;}if(memo[i]!=-1){returnmemo[i];}intans=f2(i-1,memo)+f2(i-2,memo);memo[i]=ans;returnans;}

时间复杂度:O ( n ) O(n)O(n)。动态规划的时间复杂度 = 状态个数 × 单个状态的计算时间,且每个状态只会计算一次。

  • 或者可以这样理解:记忆化搜索的递归树可以想象为一颗左斜树,但每个节点都有一个长度为 1 的右子树(用了记忆化,所以是不展开的小毛刺),于是时间复杂度 =O ( 2 n ) O(2n)O(2n)=O ( n ) O(n)O(n)
    空间复杂度:O ( n ) O(n)O(n)。memo数组。

递推

在求解动态规划的问题时,记忆化搜索与递推的代码,在形式上是高度类似的。这是由于它们使用了相同的状态表示方式和类似的状态转移。一般来说两种实现的时间复杂度是一样的。

publicstaticintfib3(intn){if(n==0){return0;}if(n==1){return1;}int[]f=newint[n+1];f[1]=1;for(inti=2;i<=n;i++){f[i]=f[i-1]+f[i-2];}returnf[n];}

时间复杂度:O ( n ) O(n)O(n)
空间复杂度:O ( n ) O(n)O(n)

在求解动态规划的问题时,记忆化搜索和递推,都确保了同一状态至多只被求解一次。但实现的策略有所不同:递推通过设置明确的访问顺序来避免重复访问,记忆化搜索通过给已经访问过的状态打标记的方式,也达到了同样的目的。

与递推相比,记忆化搜索因为不用明确规定访问顺序,在实现难度上有时低于递推,且能比较方便地处理边界情况,这是记忆化搜索的一大优势。但与此同时,记忆化搜索难以使用滚动数组,数据结构等优化,且由于存在递归,运行效率会低于递推。

优化

观察状态转移方程,发现一旦算出 f[i],那么 f[i−2] 及其左边的状态就永远不会用到了,于是我们可以用几个变量,把空间复杂度优化成O ( 1 ) O(1)O(1)

publicintfib(intn){if(n==0){return0;}if(n==1){return1;}intf0=0,f1=1;for(inti=2;i<=n;i++){intnewF=f0+f1;f0=f1;f1=newF;}returnf1;}

以下是我认为最有代表性的一些题。

爬楼梯

通常可以用「枚举选哪个」的搜索思想。
力扣 70. 爬楼梯
力扣 2266. 统计打字方案数 每次可以爬 3 或 4 层

打家劫舍

通常可以用「选或不选」的搜索思想。
力扣198. 打家劫舍 从最左或最右切入可以简化问题
力扣 740. 删除并获得点数 值域打家劫舍
力扣 3186. 施咒的最大总伤害 数据规模更大的 值域打家劫舍
力扣 2140. 解决智力问题 刷表法:用现在的状态更新未来的状态。与之对比的是查表法:用之前的状态计算当前的状态

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 21:29:00

自动驾驶世界模型核心成果、论文代码与最新进展全景解析

一、核心参与主体与技术生态布局&#xff08;一&#xff09;参与主体分类及定位主体类型代表机构/企业核心定位与研发方向车企/科技企业理想、小鹏、华为、百度、小米、吉利、滴滴、地平线、蔚来、NVIDIA、阿里高德技术落地与规模化应用&#xff0c;聚焦车端部署、仿真体系搭建…

作者头像 李华
网站建设 2026/4/16 21:44:00

Dify平台API权限控制机制的设计与实施

Dify平台API权限控制机制的设计与实施 在AI应用快速渗透企业核心业务的今天&#xff0c;一个看似不起眼的技术细节——API能不能被随意调用——往往决定了整个系统的安危。设想一下&#xff1a;某天你发现外部合作伙伴通过一个公开的接口&#xff0c;不仅调用了你的智能客服模型…

作者头像 李华
网站建设 2026/4/16 21:42:55

LobeChat能否实现多人协同编辑?共享会话功能设想

LobeChat能否实现多人协同编辑&#xff1f;共享会话功能设想 在远程办公常态化、AI助手深度融入工作流的今天&#xff0c;一个看似简单却日益凸显的问题浮出水面&#xff1a;我们能否像协作编辑一份文档那样&#xff0c;多人实时共用同一个AI对话&#xff1f; 想象这样一个场…

作者头像 李华
网站建设 2026/4/15 17:30:48

基于单片机的智能温控风扇系统设计(温度+风速调节)【附代码】

&#x1f4c8; 算法与建模 | 专注PLC、单片机毕业设计 ✨ 擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导&#xff0c;毕业论文、期刊论文经验交流。✅ 专业定制毕业设计✅ 具体问题可以私信或查看文章底部二维码本系统的核心设计内容在于构建一个以单片机…

作者头像 李华
网站建设 2026/4/16 21:40:07

Python中配置TensorFlow-GPU的完整方法

Python中配置TensorFlow-GPU的完整方法 在深度学习项目开发中&#xff0c;模型训练动辄需要数小时甚至数天&#xff0c;而能否充分利用GPU资源&#xff0c;往往决定了整个研发流程的效率。如果你还在用CPU跑ResNet或Transformer&#xff0c;那可能连一个epoch都坚持不下来就放…

作者头像 李华
网站建设 2026/4/16 21:57:05

基于单片机的智能晾衣架控制系统设计【附代码】

&#x1f4c8; 算法与建模 | 专注PLC、单片机毕业设计 ✨ 擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导&#xff0c;毕业论文、期刊论文经验交流。✅ 专业定制毕业设计✅ 具体问题可以私信或查看文章底部二维码在智能晾衣架控制系统的核心控制单元与驱动…

作者头像 李华