▎前言

  首先先来说一下RMB是什么,当然是人民币啦。

  今天我们要学的这个东西不一般,叫做RMQ问题,那么它和RMB有什么关系呢?待小编细细说来。

▎前置技能:动态规划

  不会的同志请戳这里迅速了解动态规划。

▎RMQ问题是什么

☞『定义』

  RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就是说,RMQ问题是指求区间最值的问题。(copy自百度)

  猜你也不想看,来,小编用人话翻译一下:就是说给定一堆数字(顺序位置固定且永远不变),(多次)询问你一段区间内的最大/最小值。

☞『问题解决:模拟算法』

  RMQ只是一类这样的问题,却不是一门算法。

  既然是问题,那么我们就应该解决,但是怎么解决,怎样解决,一切先从模拟算法(直白一点叫暴力)说起。

  先来想想模拟算法怎么解决,当然是给定区间后直接遍历,寻找最大/最小值呗。但是别忘了,这种题多次询问,一直遍历对于数据规模大的题简直是杯水车薪。

  此时,不得不请出动态规划。

☞『问题解决:动态规划』

  我们为什么使用动态规划呢?先来思考这个问题:为什么暴力不能满足需求。

  你肯定会说:这还不简单,暴力慢呗。

  但是暴力究竟慢在了哪里?暴力慢在了没有完全利用好整个大区间,很多东西都在重复遍历。

  那么什么东西能很好的利用大区间呢?我们就会自然的想到了动态规划(感觉属于区间动态规划)。

  既然多次询问,那么就变向的告诉了我们一定要预处理,这里我们的动态规划可以O(n log n)预处理,然后O(1)查询。

  先来思考怎么设计状态,最开始小编是这样想的,既然是区间型动态规划类问题,那么就让f[i][j]表示i~j区间内的最大/最小数吧,(以最大数为例)状态转移方程自然就是f[i][j]=max(f[i][k],f[k+1][j])。(k为随机一个i~j区间的数组下标,不过小编更喜欢取中点)

  后来发现一本通提高篇上的设计状态更好,更快捷,我设计的太慢了。一本通提高篇上是这样处理的:f[i][j]表示i~2j-1区间内的最大/最小数,那么我们可以仿照之前我的想法,分一半,就是这样的:

  

  从区间初始和结束位置改成动态规划的形式后就是这样的:f[i][j-1]和f[i+2j-1][j-1],有时候奇数和偶数是不一样的,所以小编的图可能对这两个式子来说不太标准。

  那么我们要求的最大最小值就很简单了。

  但是问题又来了,我们如何面对询问呢?

  我们可以以二为底,将这个区间内数字的个数次方(幂的逆运算)为界,进行比较两个区间大小,图解一下:

  

  那么我们就只要比较出两个区间中的最大最小值即可。两个区间改成动态规划形式就是f[x][log[d]],f[y-(1<<log[d])+1][log[d]]),其中我把d改成了y-x+1的意思。

  好了,问题又来了,log怎么处理,我们先来看一下前10个数的log处理情况:

  

  经过专业调查和探寻后,就会发现log[i]=log[i/2]+1的规律,因此我们可以预处理出log的值。

☞『这么快的算法,为什么还需要其他算法呢?』

  其实这个问题正是这个算法的弊端,因为不能支持期间修改一些数的值。

  而线段树,树状数组正巧妙的解决了这一弊端。

▎实战演练:洛谷P1816 忠诚(模板题)

  废话不多说,直接上题:


P1816 忠诚

题目描述

老管家是一个聪明能干的人。他为财主工作了整整10年,财主为了让自已账目更加清楚。要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意。但是由于一些人的挑拨,财主还是对管家产生了怀疑。于是他决定用一种特别的方法来判断管家的忠诚,他把每次的账目按1,2,3…编号,然后不定时的问管家问题,问题是这样的:在a到b号账中最少的一笔是多少?为了让管家没时间作假他总是一次问多个问题。

输入输出格式

输入格式:

输入中第一行有两个数m,n表示有m(m<=100000)笔账,n表示有n个问题,n<=100000。

第二行为m个数,分别是账目的钱数

后面n行分别是n个问题,每行有2个数字说明开始结束的账目编号。

输出格式:

输出文件中为每个问题的答案。具体查看样例。

输入输出样例

输入样例#1: 复制

10 3
1 2 3 4 5 6 7 8 9 10
2 7
3 9
1 10

输出样例#1: 复制

2 3 1

  这道题相当好做,就是模板题,所以就不解释了,直接上代码:

 1 #include<iostream>
 2 using namespace std;
 3 int m,n,a[100000],f[100000][100],x,y,log[100000];
 4 int main()
 5 {
 6     cin>>m>>n;
 7     for(int i=1;i<=m;i++)
 8     {
 9         cin>>a[i];
10         f[i][0]=a[i];
11     }
12     for(int j=1;j<=16;j++)
13     for(int i=1;i+(1<<j)-1<=m;i++)
14     f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
15     log[1]=0;
16     for(int i=2;i<=100000;i++)
17     log[i]=log[i/2]+1;
18     for(int i=1;i<=n;i++)
19     {
20         cin>>x>>y;
21         int d=y-x+1;
22         cout<<min(f[x][log[d]],f[y-(1<<log[d])+1][log[d]])<<" ";
23     }
24     return 0;
25 }

▎实战演练:一本通1541:【例 1】数列区间最大值(模板题)

  废话不多说,直接上题:


1541:【例 1】数列区间最大值

时间限制: 1000 ms         内存限制: 524288 KB
提交数: 638     通过数: 224

【题目描述】

输入一串数字,给你 M 个询问,每次询问就给你两个数字 X,Y,要求你说出 X 到 Y 这段区间内的最大数。

【输入】

第一行两个整数 N,M 表示数字的个数和要询问的次数;

接下来一行为 N 个数;

接下来 M 行,每行都有两个整数 X,Y。

【输出】

输出共 M 行,每行输出一个数。

【输入样例】

10 2
3 2 4 5 6 8 1 2 9 7
1 4
3 8

【输出样例】

5
8

【提示】

数据范围与提示:

对于全部数据,1≤N≤105,1≤M≤106,1≤X≤Y≤N。数字不超过 C/C++ 的 int 范围。

【来源】

  这道题只要把忠诚的代码改成max就可以了(还稍微有点其他细节),注意会卡常数,不能用cin和cout。代码如下:

  

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int m,n,a[1000000],f[1000000][100],x,y,log[1000000];
 5 int main()
 6 {
 7     scanf("%d%d",&m,&n);
 8     for(int i=1;i<=m;i++)
 9     {
10         scanf("%d",&a[i]);
11         f[i][0]=a[i];
12     }
13     for(int j=1;j<=18;j++)
14     for(int i=1;i+(1<<j)-1<=m;i++)
15     f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
16     log[1]=0;
17     for(int i=2;i<=m;i++)
18     log[i]=log[i>>1]+1;
19     for(int i=1;i<=n;i++)
20     {
21         scanf("%d%d",&x,&y);
22         int d=y-x+1;
23         printf("%d \n",max(f[x][log[d]],f[y-(1<<log[d])+1][log[d]])) ;
24     }
25     return 0;
26 }

转载于:https://www.cnblogs.com/TFLS-gzr/p/11221264.html

【算法•日更•第十九期】动态规划:RMQ问题相关推荐

  1. 【算法•日更•第十四期】信息奥赛一本通1592:【例 1】国王题解

    废话不多说,直接上题: 1592:[例 1]国王 时间限制: 500 ms         内存限制: 65536 KB 提交数: 290     通过数: 111 [题目描述] 原题来自:SGU 2 ...

  2. 【算法•日更•第十五期】信息奥赛一本通1594:涂抹果酱题解

    废话不多说,直接上题: 1594:涂抹果酱 时间限制: 1000 ms         内存限制: 524288 KB 提交数: 146     通过数: 46 [题目描述] Tyvj 两周年庆典要到 ...

  3. 【算法•日更•第十二期】信息奥赛一本通1585:【例 1】Amount of Degrees题解

    废话不多说,直接上题: 1585: [例 1]Amount of Degrees 时间限制: 1000 ms         内存限制: 524288 KB 提交数: 130     通过数: 68 ...

  4. CSDN 编程竞赛二十九期题解

    竞赛总览 CSDN 编程竞赛二十九期:比赛详情 (csdn.net) 竞赛题解 题目1.订班服 小A班级订班服了!可是小A是个小糊涂鬼,整错了好多人的衣服的大小.小A只能自己掏钱包来补钱了.小A想知道 ...

  5. 应用回归分析何晓群课第五版_海外第三方应用市场分析丨出海学院十九期直播课...

    Enjoy出海一站式出海服务平台 点击关注"Enjoy出海"公众号 时时参与出海答疑问题 出海学院第十九期直播课 出海学院十九期直播课,由Enjoy出海CEO金翔主讲,本期主题为& ...

  6. 开发者论坛一周精粹(第十九期) :【重要事件】运维人员注意啦:NetSarang的Xmanager和Xshell多种产品被植入后门...

    摘要: 安全公司发现官方发布的软件版本中,nssock2.dll模块源码被植入后门.由于使用该软件的技术人员较多,存在一定的安全风险. 目前官方已经发布了xshell最高版本为 Xshell 5 Bu ...

  7. 《袁老师访谈录》第十九期-【在商言商·思享会】(第一场)“企业如何抓住新一代科技红利”...

    11月21日,<袁老师访谈录>第十九期-香港科大商学院[在商言商·思享会](第一场)"企业如何抓住新一代科技红利"成功举办,现场共有近150位校友及观众到场,十大平台同 ...

  8. 2021计算机一级模拟29套,“智慧家”2021年第二十九期每周家庭套餐

    原标题:"智慧家"2021年第二十九期每周家庭套餐 玉溪妇联 架起一座与广大姐妹们沟通的桥梁 只有家长的好好学习,才能助力孩子的健康成长,只有家长和孩子不断地学习成长,才能营造和谐 ...

  9. 数据库管理-第四十九期 Exadata的存储节点管理(20221223)

    数据库管理 2022-12-23 第四十九期 Exadata的存储节点管理 1 咋个查看数据是否被缓存到闪存卡了没 2 EM13.5的Exadata监控 3 存储降级 总结 第四十九期 Exadata ...

最新文章

  1. mysql服务启动很久_Mysql服务启动问题
  2. 【转】PCA算法学习_1(OpenCV中PCA实现人脸降维)
  3. RabbitMQ管理(5)——集群管理
  4. linux系统下sed切割日志
  5. HPC+AI融合发展的挑战和应对方法探讨
  6. 前端安全问题的解决方法
  7. Web 框架之 SSH 框架的简单搭建的简单整理(基于Eclipse)
  8. jpa报错:Provided id of the wrong type for class
  9. Barsetto百胜图BAV02自助咖啡机——创新咖啡体验
  10. UNIX 进程揭秘--进程的生命周期
  11. java poi打印excel_POI打印Excel报表
  12. 关于Gson对日期的格式化
  13. JAVA基础作业练习—自定义异常之模拟ATM
  14. PS制作渐变金属文字
  15. 数据库设计之概念结构设计---------E-R图详解 (各种各样的实例)
  16. 生活 RH阴性血 AB型
  17. cpu超线程优缺点_什么是超线程,它有什么优点?
  18. 迅睿CMS 万网虚拟主机无法连接数据库
  19. Mysql之--------------------多表查询(内连接 左外连接 右外连接)常见的数据库函数
  20. 永辉系统服务器,永辉超市供应商服务系统(永辉超市供应商供零系统)

热门文章

  1. 关于Java垃圾回收问题的总结
  2. Myeclipse 2014 破解补丁 附官方安装包与图文使用方法
  3. ES6 语法糖(一)
  4. 成神结局量子计算机雏惨,成神之日:消失数月之后雏再次出现,不过形象却差点让人认不出...
  5. 20180903文件系统和文件管理
  6. 盲盒系统搭建——玩转盲盒系统
  7. html5svg简介
  8. 基于图像的三维重建研究
  9. 国产FPGA厂商及产品
  10. 【技术整合】各技术解决方案与对应解决的问题