算法刷题记录(Day 33)
Balanced Lineup(poj 3264)
原题链接
题目类型:RMQ、ST表
RMQ视频讲解
RMQ以及ST表
存在的问题:
1.2的幂次应该如何计算->打表
2.log2 x转化为log x/log 2
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
#define NMAX 50005
#define BMAX 20
int dpmx[NMAX][BMAX];
int dpmn[NMAX][BMAX];
int e2[BMAX];
int N, Q;
int cur;
int a, b;
int main() {cin >> N >> Q;for (int i = 1; i <= N; i++) {cin >> cur;dpmx[i][0] = dpmn[i][0] = cur;}//预处理e2[0] = 1;for (int i = 1; i < BMAX; i++) e2[i] = 2 * e2[i - 1];for (int i = 1; i < BMAX; i++) {for (int j = 1; j <= N; j++) {if (j + e2[i] <= N+1) { //可能会存在溢出的问题,因为dp[i][j]代表的是[i,i+e2[j])是左开右闭的区间,因此需要增加到N+1dpmx[j][i] = max(dpmx[j][i - 1], dpmx[j + e2[i - 1]][i - 1]);dpmn[j][i] = min(dpmn[j][i - 1], dpmn[j + e2[i - 1]][i - 1]);//cout << "from " << j << "to " << j + e2[i] << " " << dpmx[j][i] << " " << dpmn[j][i] << endl;}}}for (int i = 0; i < Q; i++) {cin >> a >> b;cur = int(log(double(b+1 - a)) / log(double(2)));//注意这里没有包括b在内//cout << a << " " << a + e2[cur] << " " << b + 1 - e2[cur] << " " << b + 1 << endl;//cout << dpmx[a][cur]<< " " << dpmx[b + 1 - e2[cur]][cur] << " " << dpmn[a][cur]<< " "<<dpmn[b + 1 - e2[cur]][cur] << " " << endl;cout << max(dpmx[a][cur], dpmx[b + 1 - e2[cur]][cur]) - min(dpmn[a][cur], dpmn[b + 1 - e2[cur]][cur]) << endl;}
}
tip:
1.代码禁止成段复制,例如本题中对于dpmx和dpmn的初始化,否则会导致错误。
2.注意题目所给出的范围是一个左闭右闭的区间,而dp[i][j]则是一个左开右闭得区间,因此在查询得时候需要进行加1的操作。
Frequent values(poj 3368)
原题链接
题目类型:RMQ
问题:
1.如何初始化
2.dp[i][j]代表的是最大的一个次数,不能是简单地进行一个max或者min操作,因此出现的次数在两个不重合的区间内应该是可以相加的
解答:首先不能直接用st表去维护区间内重复的个数,因为这在本质上是一个可以相加的量,而RMQ则是关于区间极值求解的问题。而抓住题目中非降的特性,可以将相同的值处理为一个块,而将待求解的区间也依照值得相同为块进行划分,每个块得值为其中含有的元素得个数,那么就可以转化为RMQ(注意这仅仅只是对于完全包含在区间内的点来说的)。
具体来说,假设区间范围为(s,t),其所在块分别为S和T。
若S和T相等,则位于一个块,返回t-s+1.
若不等,首先将S块和T块剔除,即使用S块得结束位置减去s计算S块的个数,使用t减去T块的起始得到T块的个数,最后再使用RMQ处理中间的部分得到一个最大值。
//tle
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
#define NMAX 100010
#define BMAX 30
int dpmx[NMAX][BMAX];
int e2[BMAX];
int n, q, cur;
struct node {int start, finish;int num;
}block[NMAX];
int block_num = 0;
int lot[NMAX];
int main() {//预处理e2[0] = 1;for (int i = 1; i < BMAX; i++) e2[i] = 2 * e2[i - 1];while (1) {cin >> n;if (!n) break;cin >> q;int pre = 100001;block_num = 0;for (int i = 1; i <= n; i++) {cin >> cur;if (cur != pre) {if (i != 1) block_num++;block[block_num].num = 0;if (block_num > 0) block[block_num - 1].finish = i - 1;block[block_num].start = i;}pre = cur;lot[i] = block_num;block[block_num].num++;}block[block_num].finish = n;//for (int i = 0; i <= block_num; i++) printf("%d %d %d\n", block[i].start, block[i].finish, block[i].num);//以块为单位建立st表for (int i = 0; i <= block_num; i++) dpmx[i][0] = block[i].num;for (int i = 1; e2[i] <= block_num; i++) {for (int j = 0; j <= block_num; j++) {if (j + e2[i] <= block_num + 1) dpmx[j][i] = max(dpmx[j][i - 1], dpmx[j + e2[i - 1]][i - 1]);}}for (int i = 0; i < q; i++) {int s, t;cin >> s >> t;int S = lot[s], T = lot[t];int res;if (S == T) res = t - s + 1;else {res = max(block[S].finish - s + 1, t - block[T].start + 1);S++;if (T > S) {int cur = log(double(T - S)) / log(double(2));res = max(res, max(dpmx[S][cur], dpmx[T - e2[cur]][cur]));}}cout << res << endl;}}}
tip:
奇怪的超时
算法刷题记录(Day 33)相关推荐
- Ants (POJNo.1852)--数据结构与算法刷题记录
数据结构与算法刷题记录1 时间:4.28 这是第一次用CSDN来记录自己的学习成果,在此留下纪念,希望自己能够坚持下去,变得更强. 本次学习记录来源于<挑战程序设计竞赛(第2版)> Ant ...
- 数据结构与算法刷题记录
数据结构与算法&程序语言 学习物料汇总: leetcode&牛客网 流畅的python 书签&网络搜索 leetcode 数据结构 数组 链表 栈&队列 字符串 算法 ...
- 算法刷题记录(Day 16)
棋局评估(csp 201803-4) 题目类型:博弈论.dfs.最大最小搜索 思路一:去模拟下棋,Alice和Bob轮流下棋,每次使用"最优策略"来决定下在哪里. "最优 ...
- 算法刷题记录(Day 12)
Surprising Strings(poj 3096) 原题链接 解题思路:对于每一个D-pair的D值,生成相应的组,并存放在set中,若发现重复,则直接退出,否则代表成功. #include&l ...
- leetcode算法刷题记录之罗马数字转整数
题目描述: 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X ...
- $2019$ 暑期刷题记录 $2$(基本算法专题)
$ 2019 $ 暑期刷题记录 $ 2 $ (基本算法专题) $ by~~wch $ $ BZOJ~1958~Strange~Towers~of~Hanoi $ (动态规划,递推) 题目大意: 求有 ...
- 算法笔记CodeUp第一至第六章刷题记录
文章目录 <算法笔记>2.2小节--C/C++快速入门->顺序结构 1.例题1-1-1 按要求输出信息(1) 2.例题1-1-2 按要求输出信息(2) 3.例题1-2-1 求两个整数 ...
- 算法记录 牛客网 leetcode刷题记录
算法记录 & 牛客网 & leetcode刷题记录 解题思路 STL容器 常用算法模板 堆排序 插入排序 快速排序 BFS层序遍历 二叉树 JZ55 二叉树的深度 BST(binary ...
- BZOJ刷题记录---提高组难度
BZOJ刷题记录---提高组难度 总目录详见https://blog.csdn.net/mrcrack/article/details/90228694 序号 题号 算法 思想难度 实现难度 总难度 ...
最新文章
- ks检验正态分布结果_【学习】AD, RJ和KS哪种正态性检验是最好的?
- Httprunner生成Allure格式HTML报告
- groovy import java_在Java中调用Groovy方法的又一种方法:使用接口
- 轻量级3d模型查看器_耐能取得两项软件著作权,自研轻量级3D人脸识别算法领先业界...
- Undo TableSpace ①.管理方法
- Django模型层的多表操作(2)
- 无盘服务器 机械盘,Win7启动速度研究,同样的PC配置,机械盘、固态盘、无盘网络启动速度为何不同?...
- mat 内存分析 Linux,JVM内存分析工具MAT使用简介
- ElasticSearch5.4X 搜索引擎查询java工具类
- web安全day34:一步一步学习Linux防火墙
- 如何用c语言批量替换字符串,[C/C++]急速批量替换字符串
- J-LINK烧录bin文件
- Android计分器课程设计,课程设计题八:篮球比赛计分器
- conda安装hanlp报错“找不到JAVA,请安装JAVA8”
- 怎么做应力应变曲线_如何用Origin画应力应变曲线
- PS教程:利用灰度蒙版实现无级调节
- 简易数字时钟 按键可校准
- 计算机考研统考压分吗,担忧!考研初试会被压分吗?
- 2021年安全生产模拟考试(全国特种作业操作证电工作业-防爆电气模拟考试题库一)安考星
- 摄影构图学83年绝版_让模特露肩、露腿的摄影师们,我求求你别再祸害“古风摄影”了!...