记忆化搜索

news2024/9/25 23:17:25

一.记忆化搜索概述

1.概念

        搜索是一种简单有效但是效率又很低下的算法结构,其低效的原因主要在于存在很多重叠子问题。而记忆化搜索则是在搜索的基础上,利用数组来记录已经计算出来的重叠子问题状态,进行合理化的剪枝,从而降低时间复杂度。这个记录状态的过程就是记忆化的过程,我们需要找到不同搜索层次之间的子问题、状态转移关系,这与动态规划的思想又不谋而合。

        简单来说,记忆化搜索是一种典型的空间换时间的思想,记忆化搜索 = 深度优先搜索实现 + 动态规划思想(记录状态、剪枝)。

2.图示

        此处以某个记忆化搜索题目的结构树为例。在搜索过程中,我们将问题的搜索树画出来如下所示。左侧为暴力搜索的搜索树,而右侧为记忆化搜索剪枝的搜索树。

         记忆化搜索可以看作是动态规划的前置过程,或者说记忆化搜索一般是自顶向下的,而动态规划一般是自底向上的。

二.例题

1.LeetCode 45. 跳跃游戏改

        给定一个长度为 n 的整数数组 nums。初始位置为 nums[0]。每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处(0 <= j <= nums[i])

        返回到达 nums[n - 1] 的最小跳跃次数。已知跳跃次数有上限K,若无法在K次内到达则返回 -1

(1)记忆化搜索 

        对于该题,我们可以先求出到达终点的最小跳跃次数 t,然后比较 t 与上限 K 的大小,若t > K则返回 -1 。

        按照搜索的思想来说,我们在到达某个索引 i 时,该位置到达终点的最小跳跃次数取决于 min(dfs(i) , dfs(i+j) + 1),0 <= j <= nums[i] ;按照记忆化的思想,像最短路一样,某个位置 i 到达终点的最小跳跃次数应该是确定的,属于重叠子问题,不应该重复搜索,因此可以使用数组记录每个位置的最小次数。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10000 + 7;
int n,k,nums[maxn],mem[maxn];

int dfs(int index){
    if(index >= n-1)return 0;
    if(mem[index]!=-1)return mem[index];//记忆化
    int ans = -1;
    for(int i = 1;i<=nums[index];i++){
        int res = dfs(index+i)+1;
        if(res != 0){
            ans = ans==-1?res:min(ans,res);
        }
    }
    return mem[index] = ans;
}

int main()
{
    memset(mem,-1,sizeof(mem));
    scanf("%d%d",&n,&k);
    for(int i = 0;i<n;i++){
        scanf("%d",&nums[i]);
    }
    dfs(0);
    if(mem[0] == -1 || mem[0] > k)printf("-1\n");
    else printf("%d\n",mem[0]);
}

(2)贪心

        记忆化搜索的方式可行,但是复杂度还是有点高会超时。我们重新来审视这个题,每个位置处的跳跃距离是固定的、相互独立的,与之前的子节点和之后的子节点都是没关系的,也就是说该题其实与动态规划思想无关。

        考虑现在跳到了位置 i ,那么接下来应该选择跳到 i+1 ~ i+nums[i] 的哪个位置呢?答案是「贪心」地选择能跳跃到距离最后一个位置最远的那个位置(即使得“探索序列”能够拓宽最远的那个位置),原因是以该位置为下一次起跳点所能到达的地方,由于其是最远的,所以能够覆盖其他所有的起跳点位置范围,这肯定是最优的。

        当一次 跳跃 结束时,从下一个格子开始,到现在 能跳到最远的距离 是下一次 跳跃 的 起跳点。所以跳完一次之后,不断更新维护下一次 起跳点的范围。在新的范围内跳,更新 能跳到最远的距离

int jump(int len){
    int ans = 0;
    int start = 0,last = 0; //初始起跳范围 [0,0] 闭区间
    while(last < len - 1){
        int maxpos = 0;
        //选择下一次跳哪个
        for(int i = start;i<=last;i++){
            maxpos = max(maxpos,i+nums[i]);
        }
        start = last+1; // 下一次起跳点范围开始的格子
        last = maxpos;  // 下一次起跳点范围结束的格子
        ans++; // 跳跃次数
    }
    return ans;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/367219.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

程序员如何发展第二职业?这几种副业方式超赚钱

很多程序员曾表示&#xff0c;虽然月薪一两万&#xff0c;但有时候还是会焦虑。 尤其是遇上了年初裁员年底裁员这样的就业环境&#xff0c;焦虑就会逐步放大&#xff0c;这时候副业赚钱的重要性就体现出来了。 发展第二职业&#xff0c;可以让程序员们增加抗风险能力&#xf…

扩展学习之时间戳趣谈

目录 一、介绍 二、转换工具 三、获取Unix时间戳的指令 四、普通时间转Unix时间戳 五、扩展 一、介绍 时间戳&#xff1a;一份数据在特定时间点存在的可验证的数据。 Unix时间戳&#xff08;英文为Unix epoch, Unix time, POSIX time 或 Unix timestamp&#xff09;&…

(二十七)大白话在Buffer Pool执行完增删改之后,写入日志文件的redo log长什么样?

昨天我们简单给大家回顾了一下在数据库里执行增删改操作的时候&#xff0c;redo log是用来干什么的&#xff0c;为什么需要这个东西&#xff0c;如果没有他会怎么样&#xff0c;有了他之后又能有什么样的效果&#xff0c;想必大家现在都对redo log这个东西有一定的理解了。 那…

高性能低功耗4口高速USB2.0 HUB 完美替代FE1.1S和FE8.1

该NS1.1s是一个高度集成的&#xff0c;高品质&#xff0c;高性能&#xff0c;低功耗&#xff0c;为USB 2.0高速4端口集线器又低成本的解决方案。 &#xff08;点击即可咨询芯片详细信息&#xff09; NS1.1s的特点 1.通用串行总线规范修订版2.0&#xff08;USB 2.0&#xff09;完…

LeetCodeHOT100热题01

写在前面 主要分类一下刷题遇到的一些题型。有很多思路的图都来源于力扣的题解&#xff0c;如侵权会及时删除。不过代码都是个人实现的&#xff0c;所以有一些值得记录的理解。之前的算法系列参看&#xff1a; 剑指offer算法题01剑指offer算法题02 一、哈希表 1. 两数之和 …

自然语言处理(NLP)之近似训练法:负采样与层序Softmax

我们在前面介绍的跳字模型与连续词袋模型有个缺陷就是在计算梯度时的开销随着词典增大会变得很大&#xff0c;因为每一步的梯度计算都包含词典大小数目的项的累加。为了降低这种带来的高计算复杂度&#xff0c;介绍两种近似的处理方案&#xff1a;负采样和层序softmax负采样(Ne…

PADS新建封装中焊盘部分修正

在PADS新建封装中&#xff0c;需要修改焊盘参数。因为之前做板&#xff0c;有问题工厂都会帮忙修正&#xff0c;所以忽略了焊盘中阻焊层和助焊层。这里专门做一个修正。进入焊盘栈编辑界面之后&#xff0c;需要点击“添加层”&#xff0c;然后选择阻焊层顶层&#xff08;Solder…

以太网分析仪

以太网分析仪顾名思义&#xff0c;就是针对网络性能方面的网络丢包、延迟、抖动等问题进行分析哪个环节出现了问题&#xff0c; 这种网络测试仪&#xff0c;市面上的品牌还是比较多的&#xff0c;价格也是有高有低&#xff0c;那么&#xff0c;如何从这么多仪器仪表里面选择一款…

JS逆向之BackTest入门滑块与表单加密

声明&#xff1a;本文仅限学习交流使用&#xff0c;禁止用于非法用途、商业活动等。否则后果自负。如有侵权&#xff0c;请告知删除&#xff0c;谢谢&#xff01;本教程也没有专门针对某个网站而编写&#xff0c;单纯的技术研究 一、本期逆向 1.网站&#xff1a;aHR0cDovL2JhY…

聊聊 HTAP 的前世今生

随着现代社会大型实时分析应用的逐渐流行&#xff0c;关系型数据库已经难以处理高并发的事务请求。商业层面上&#xff0c;当全球进入数字化时代&#xff0c;数字化技术渗透到各行各业&#xff0c;同时产生了海量数据&#xff0c;数据的存储和应用是企业决策的重要依据之一&…

计网数据链路层

第二层:数据链路层 数据链路层传输单位为帧 数据链路层三大问题&#xff1a;封装成帧&#xff0c;差错检测&#xff0c;可靠传输 两个协议&#xff1a; 共享式以太网的媒体接入控制协议CSMA/CD 802.11局域网的媒体接入控制协议CSMA/CA 在封装成帧的问题中&#xff0c;数据链路层…

100种思维模型之诺依曼思维模型-019

生活中&#xff0c;难免总会遇到一些“大”、“笼统”、“难入手”的问题&#xff01; 如&#xff0c;前几天突然接到领导安排&#xff0c;帮忙梳理一个材料“***景区创建5A级旅游景区提升规划”。 对于一个没有学过景区提升规划、没有做过规划的我来说&#xff0c;真的挺难的…

Mysql 索引(三)—— 不同索引的创建方式(主键索引、普通索引、唯一键索引)

了解了主键索引的底层原理&#xff0c;主键索引其实就是根据主键字段建立相关的数据结构&#xff08;B树&#xff09;&#xff0c;此后在使用主键字段作为条件查询时&#xff0c;会直接根据主键查找B树的叶子结点。除了主键索引外&#xff0c;普通索引和唯一键索引也是如此&…

URP渲染管线光照机制剖析

上一节通过剖析URP 摄像机了解摄像机的机制&#xff0c;本节来分析URP的光照的主要机制&#xff0c;并通过与内置的向前渲染管线做对比&#xff0c;来比较它们的与不同。 对啦&#xff01;这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白&#xff0c;也有一些…

[机器学习]XGBoost---增量学习多阶段任务学习

一 说明当我们的训练数据非常多&#xff0c;并且还在不断增加时&#xff0c;每次都用全量训练&#xff0c;数据过多&#xff0c;时间过长&#xff0c;此时就可以使用增量训练&#xff1a;用新增的数据微调校正模型。二 全量与增量的差异在使用增量训练时&#xff0c;最关心的问…

矩阵通高效监管企业新媒体矩阵,账号集中管理与运营数据分析

越来越多的企业在全网布局旗下账号&#xff0c;希望通过社媒传播矩阵&#xff0c;以内容连接产品与用户&#xff0c;达成增加销售线索或扩大品牌声量的目的。构建矩阵的优势在于&#xff0c;内容能多元发展&#xff0c;聚集不同平台流量&#xff1b;多种营销渠道自主掌控&#…

高并发系统设计之限流

本文已收录至Github&#xff0c;推荐阅读 &#x1f449; Java随想录 文章目录限流算法计数器算法滑动窗口漏桶算法令牌桶算法限流算法实现Guava RateLimiter实现限流令牌预分配预热限流Nginx 限流limit_connlimit_req黑白名单限流这篇文章来讲讲限流&#xff0c;在高并发系统中…

【包装工单批次编号不存在】和【MES没有样品单报工数据】

包装工单批次编号不存在 今天在做数据的时候,发现一个诡异的问题,有几个包装工单明细里没有批次编号。 我问了下假捻的同事,他们说很奇怪,有的时候有,有的时候没有。 我又咨询了供应商,供应商说不可能没有,批次编号的业务逻辑是通过物料编码+区分号+等级+包装方式 4个…

多模态机器学习入门——文献阅读(一)Multimodal Machine Learning: A Survey and Taxonomy

文章目录说明论文阅读AbstractIntroductionIntroduction总结Applications&#xff1a;A Historical Perspective补充与总结3 MULTIMODAL REPRESENTATIONS总结Joint Repersentations&#xff08;1&#xff09;总结和附加(一)Joint Repersentations&#xff08;2&#xff09;总结…

问题总结:Map存入的数据丢失类型任意

发现问题&#xff1a;Map存入的数据丢失类型 经常会使用 Map<String&#xff0c;Object> 来用于存储键值对的数据&#xff0c;由于我们使用 Object 类型来接收数字&#xff0c;但是有些时候会出现map并不知道我们传入的是 Long 还是 Integer 。也就是出现数据类型丢失的…