news 2026/5/25 18:26:59

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

作者头像

张小明

前端开发工程师

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/5/25 0:32:04

kotaemon社区支持全攻略:从入门到答疑

Kotaemon社区支持全攻略&#xff1a;从入门到答疑 在企业级智能问答系统的开发过程中&#xff0c;许多团队都曾被几个关键问题困扰&#xff1a;模型回答“一本正经地胡说八道”&#xff0c;检索结果与问题毫不相关&#xff0c;部署流程复杂得像拼乐高——每一步都可能卡住。而…

作者头像 李华
网站建设 2026/5/23 1:45:11

GPT-SoVITS模型部署避坑指南:npm安装依赖常见问题汇总

GPT-SoVITS模型部署避坑指南&#xff1a;npm安装依赖常见问题汇总 在当前AI语音技术快速落地的背景下&#xff0c;个性化语音合成已不再是科研机构的专属能力。越来越多的开发者尝试将如 GPT-SoVITS 这类先进的开源项目部署到本地或私有服务器上&#xff0c;用于虚拟主播、有声…

作者头像 李华
网站建设 2026/5/24 17:54:06

AutoGPT项目使用教程:快速上手指南

AutoGPT 使用指南&#xff1a;从零开始构建你的自主智能体 你有没有想过&#xff0c;让 AI 自己决定“下一步该做什么”&#xff1f;不是简单地回答问题&#xff0c;而是像一个真正的助手那样&#xff0c;拿到目标后主动拆解任务、搜索资料、写文档、运行代码&#xff0c;直到…

作者头像 李华
网站建设 2026/5/25 7:53:58

SpEL 表达式详解

SpEL表达式&#xff08;Spring Expression Language&#xff09;详解 SpEL&#xff08;Spring Expression Language&#xff09;是Spring框架提供的一种强大的表达式语言&#xff0c;用于在运行时查询和操作对象图&#xff0c;支持字面量、运算符、方法调用、属性访问、正则匹配…

作者头像 李华
网站建设 2026/5/25 18:22:35

基于单片机的花卉温室湿度与光照监测系统设计【附代码】

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

作者头像 李华
网站建设 2026/5/25 8:21:08

基于单片机的智能灯光调节系统设计(亮度+人体感应)【附代码】

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

作者头像 李华