文章目录

  • RMQ问题
  • ST算法
  • 模板
  • 例题
    • P2251 质量检测
    • P1816 忠诚
    • P2216 [HAOI2007]理想的正方形

RMQ问题


RMQ(Range Minimum/Maximum Query)问题,是求区间最大值或最小值,即范围最值问题。暴力解法是对每个询问区间循环求解,设区间长度nnn,询问次数mmm,则复杂度是O(nm)O(nm)O(nm)。一般还可以使用线段树求解,复杂度是O(mlogn)O(mlogn)O(mlogn)。但还有一种更简便的ST算法,预处理复杂度是O(nlogn)O(nlogn)O(nlogn),查询O(1)O(1)O(1)。

ST算法


ST(Sparse Table)即稀疏表,运用了动态规划的思想,设dp[i][j]dp[i][j]dp[i][j]表示第iii处开始的2j2^j2j个数字的最值,iii是开始位置,jjj是延伸长度,dp[i][0]dp[i][0]dp[i][0]则是原数组a[i]a[i]a[i]本身,是边界。原理类似倍增,首先比较每2个元素的最值,然后再通过比较这2个最值,得到4个元素的最值,以此类推8个、16个……。

状态转移方程:dp[i][j]=min(dp[i][j−1],dp[i+2(j−1)][j−1])dp[i][j]=min(dp[i][j-1],dp[i+2^{(j-1)}][j-1])dp[i][j]=min(dp[i][j−1],dp[i+2(j−1)][j−1])。
即长度为2j2^j2j区间的最值是左右两半长度为2j−12^{j-1}2j−1子区间中最值较小的一个,而两个子区间的起始位置不难推出,分别是iii和i+2j−1i+2^{j-1}i+2j−1。max最大值同理。

查询时,需要找到两个区间完全覆盖[l,r][l,r][l,r],也就是需要计算出kkk,使2k<r−l+1<2k+12^k<r-l+1<2^{k+1}2k<r−l+1<2k+1,换句话说就是,从左端点lll开始的2k2^k2k个数和以右端点结尾的2k2^k2k个数覆盖区间[l,r][l,r][l,r],即min(dp[l][k],dp[r−2k+1][k])min(dp[l][k],dp[r-2^k+1][k])min(dp[l][k],dp[r−2k+1][k])。

模板


洛谷P3865 【模板】ST表

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100005;
ll a[maxn];
ll dp[maxn][21];
void st(int n) {for (int i = 1; i <= n; i++)dp[i][0] = a[i];for (int j = 1; j <= 21; j++) {for (int i = 1; i + (1 << j) - 1 <= n; i++) {dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);}}
}
int query(int l, int r) {int k = log2(r - l + 1);return max(dp[l][k], dp[r - (1 << k) + 1][k]);
}
int main() {int n, m, l, r;scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++)scanf("%lld", &a[i]);st(n);while (m--) {scanf("%d%d", &l, &r);printf("%lld\n", query(l, r));}return 0;
}

例题


P2251 质量检测

洛谷P2251 质量检测

题目描述
为了检测生产流水线上总共 NN 件产品的质量,我们首先给每一件产品打一个分数 AA 表示其品质,然后统计前 MM 件产品中质量最差的产品的分值 Q[m] = min{A_1, A_2, … A_m}以及第 2 至第 M + 1件的Q[m + 1], Q[m + 2] Q[m+1],Q[m+2]… 最后统计第 N - M + 1至第N件的Q[n]。根据 Q 再做进一步评估。
请你尽快求出 Q 序列。
输入格式
输入共两行。
第一行共两个数 N、M,由空格隔开。含义如前述。
第二行共 N 个数,表示 N 件产品的质量。
输出格式
输出共 N - M + 1行。
第 1 至 N - M + 1行每行一个数,第i行的数 Q[i + M - 1]。含义如前述。
输入输出样例
输入 #1
10 4
16 5 6 9 5 13 14 20 8 12
输出 #1
5
5
5
5
5
8
8
说明/提示
[数据范围]
30%的数据,N≤1000
100%的数据,N≤100000
100%的数据,M≤N,A≤1000000

用单调队列也能做,ST模板练手。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000006;
int dp[maxn][21];
int n, m, k;
int main() {cin >> n >> m;for (int i = 1; i <= n; i++)cin >> dp[i][0];for (int j = 1; j <= 21; j++)for (int i = 1; i + (1 << j) - 1 <= n; i++)dp[i][j] = min(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);k = log2(m);for (int i = 1; i + m - 1 <= n; i++)cout << min(dp[i][k], dp[i + m - (1 << k)][k]) << "\n";return 0;
}

(插播反爬信息 )博主CSDN地址:https://wzlodq.blog.csdn.net/

P1816 忠诚

洛谷P1816 忠诚

题目描述
老管家是一个聪明能干的人。他为财主工作了整整10年。财主为了让自已账目更加清楚,要求管家每天记 k次账。由于管家聪明能干,因而管家总是让财主十分满意。但是由于一些人的挑拨,财主还是对管家产生了怀疑。于是他决定用一种特别的方法来判断管家的忠诚,他把每次的账目按 1, 2, 3… 编号,然后不定时的问管家问题,问题是这样的:在a 到b 号账中最少的一笔是多少?为了让管家没时间作假,他总是一次问多个问题。
输入格式
输入中第一行有两个数 m, nm,n,表示有 mm 笔账 nn 表示有 nn 个问题。
第二行为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
说明/提示
对于100% 的数据,m≤105 ,n≤105

练手+1

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int dp[maxn][21];
int n, m, l, r, k;
int main() {cin >> n >> m;for (int i = 1; i <= n; i++)cin >> dp[i][0];for (int j = 1; j <= 21; j++)for (int i = 1; i + (1 << j) - 1 <= n; i++)dp[i][j] = min(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);while (m--) {cin >> l >> r;k = log2(r - l + 1);cout << min(dp[l][k], dp[r - (1 << k) + 1][k]) << " ";}return 0;
}

P2216 [HAOI2007]理想的正方形

洛谷P2216 [HAOI2007]理想的正方形

题目描述
有一个ab的整数组成的矩阵,现请你从中找出一个nn的正方形区域,使得该区域所有数中的最大值和最小值的差最小。
输入格式
第一行为3个整数,分别表示a,b,n的值
第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。每行相邻两数之间用一空格分隔。
输出格式
仅一个整数,为ab矩阵中所有“nn正方形区域中的最大整数和最小整数的差值”的最小值。
输入输出样例
输入 #1
5 4 2
1 2 5 6
0 17 16 0
16 17 2 1
2 10 2 1
1 2 2 2
输出 #1
1
说明/提示
问题规模
(1)矩阵中的所有数都不超过1,000,000,000
(2)20%的数据2<=a,b<=100,n<=a,n<=b,n<=10
(3)100%的数据2<=a,b<=1000,n<=a,n<=b,n<=100

二维RMQ

#include<bits/stdc++.h>
using namespace std;
int a, b, n, k;
int v[1003][1003];
int maxv[1003][1003], minv[1003][1003];
int query(int x, int y) {int mx = 0, mi = 0;mx = max(maxv[x][y], max(maxv[x + n - (1 << k)][y + n - (1 << k)], max(maxv[x + n - (1 << k)][y], maxv[x][y + n - (1 << k)])));mi = min(minv[x][y], min(minv[x + n - (1 << k)][y + n - (1 << k)], min(minv[x + n - (1 << k)][y], minv[x][y + n - (1 << k)])));return mx - mi;
}
int main(){cin >> a >> b >> n;for (int i = 0; i < a; i++)for (int j = 0; j < b; j++) {cin >> v[i][j];maxv[i][j] = minv[i][j] = v[i][j];}k = log2(n);for (int ki = 0; ki < k; ki++)for (int i = 0; i + (1 << ki) < a; i++)for (int j = 0; j + (1 << ki) < b; j++) {maxv[i][j] = max(maxv[i][j], max(maxv[i + (1 << ki)][j + (1 << ki)], max(maxv[i + (1 << ki)][j], maxv[i][j + (1 << ki)])));minv[i][j] = min(minv[i][j], min(minv[i + (1 << ki)][j + (1 << ki)], min(minv[i + (1 << ki)][j], minv[i][j + (1 << ki)])));}int ans = INT_MAX;for (int i = 0; i <= a - n; i++)for (int j = 0; j <= b - n; j++)ans = min(ans, query(i, j));cout << ans;return 0;
}

原创不易,请勿转载(本不富裕的访问量雪上加霜 )
博主首页:https://wzlodq.blog.csdn.net/
来都来了,不评论两句吗

动态规划-RMQ问题(ST算法)相关推荐

  1. RMQ的ST算法(区间最值)

    ST算法求解RMQ问题(区间最值) 效率:O(n log n)预处理,O(1)询问 思想: 用 f [ i ][ j ] 表示 以i 开头的区间,包括2^j 个元素的一段区间的最值 那么有初始化的初始 ...

  2. RMQ问题(线段树算法,ST算法优化)

    RMQ (Range Minimum/Maximum Query)问题是指: 对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在[i,j]里的最小(大)值 ...

  3. RMQ问题,加深对ST算法的理解(Sparse Table)

    Sparse Table(稀疏表):简称ST 简介 ST 算法本质是动态规划. 时间复杂度为: 预处理:O(nlogn) 查询:O(1) 它 适宜用于 数据不再作出变化(也称离线) 的 区间最值 查询 ...

  4. ST算法解决RMQ问题

    关于ST算法,实际上它本身并不难,它的思想是动态规划.主要用来求RMQ问题,时间复杂度为O(NlgN+M)  关于RMQ问题描述: 输入N个数和M次询问,每次询问一个区间[L,R],求第L个数到R个数 ...

  5. 【原创】RMQ - ST算法详解

    ST算法: ID数组下标: 1   2   3   4   5   6   7   8   9     ID数组元素: 5   7   3   1   4   8   2   9   8 1.ST算法 ...

  6. RMQ ST算法简介

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

  7. ST算法 - RMQ(区间最值问题)—— 倍增

    文章目录 引入倍增: 例题1:区间和 例题2:Genius ACM 应用: ST算法 求解 RMQ(区间最值问题) 模板Code: 练习题: ST算法 维护区间最大公约数 例题:Pair of Num ...

  8. 1470: 区间求最值(RMQ问题,ST算法模板)

    1470: 区间求最值 Time Limit: 1 Sec Memory Limit: 128 MB [Submit][Status][Web Board] Description 给定一个长度为N ...

  9. RMQ+1/-1算法

    RMQ+1/-1问题要求数列中相邻两个元素相差+1或-1.利用这个限定条件可以使该算法复杂度总体上达到<O(n),O(1)>.具体做法是: 1) 设数列A的大小为n,先对数列A分组,每组大 ...

最新文章

  1. 【小知识】System.getProperties()获取系统环境变量
  2. 数学建模matlab实验报告,数学建模实验.doc
  3. java properties $,如何引用java.util.Properties中的另一个属性?
  4. idc机房安装服务器系统,IDC机房如何部署IP KVM
  5. Redis安装与开机启动
  6. 2017.10.14晚,用迅雷下载大部分BT资源出现失败,tracker服务器被封了?FK
  7. VSCode自定义网络背景皮肤
  8. xxx.so has text relocations. This is wasting memory and is a security risk. Please fix
  9. Python自动化办公:27行代码实现将多个Excel表格内容批量汇总合并到一个表格
  10. uniapp取消ios软键盘上白色导航条
  11. 数学史上的三次数学危机
  12. Java爬虫Jsoup爬取必应壁纸
  13. Kafka eagel 网页能打开,但是登录不上
  14. Alienware M11x R2 退居二线,家人工作用机
  15. 大事 | 生活终于对我的联想Y430P下手了!
  16. ONVIF 获取RTSP URL过程
  17. potplayer录制视频包含字幕
  18. 【文末有惊喜!】iOS日历攻略:提醒调休并过滤法定节假日
  19. 揭晓计算机的神秘面纱——计算机是如何工作的(一)
  20. 网上能干啥副业?适合网上干的副业,副业兼职做什么好?

热门文章

  1. fft重叠帧_PD雷达谱分析中的帧重叠ZoomFFT优化设计
  2. CAD制图初学入门:CAD图块功能的使用技巧
  3. Educational Codeforces Round 101 (Rated for Div. 2) D. Ceil Divisions(思维)
  4. 第十六届全国大学生智能汽车竞赛---英飞凌芯片支持计划
  5. 如何玩赚微信小程序分销商城
  6. 电子学会图形化一级编程题解析:希神吓走猫头鹰
  7. 新版支付宝手机网站支付、支付宝pc支付、支付宝无密退款实现
  8. 信息系统服务器故障应急处理规程,城北社区卫生服务中心信息系统应急预案
  9. 又收到一只瑞星寄来的卡卡狮……汗!
  10. JavaScript 中的 setTimeout 和 setInterval 方法