奶牛排序——RMQ
【问题描述】
奶牛在熊大妈的带领下排成了一条直队。
显然,不同的奶牛身高不一定相同……
现在,奶牛们想知道,如果找出一些连续的奶牛,要求最左边的奶牛 A 是最矮的,最右
边的 B 是最高的,且 B 高于 A 奶牛,且中间如果存在奶牛,则身高不能和 A、B 奶牛相同,
问这样的一些奶牛最多会有多少头。
从左到右给出奶牛的身高,请告诉它们符合条件的最多的奶牛数(答案可能是零、二,
但不会是一)。
【输入格式】
第一行一个数 N(2<=N<=100000),表示奶牛的头数。
接下来 N 个数,每行一个数,从上到下表示从左到右奶牛的身高(1<=身高
<=maxlongint)。
【输出格式】
一行,表示最多奶牛数。
【输入样例】Tahort.in
5
1
2
3
4
1
【输出样例】Tahort.out
4
【 样例解析 】
取第 1 头到第 4 头奶牛,满足条件且为最多。
这道题的思路如下:我们可以首先找到整个区间内最高的牛所在的位置和最矮的牛所在的位置。这样的话,答案区间就不可能越过这两头牛了,之后将区间分开递归求解即可。如果高的牛(maxn)在矮的牛(minn)前面,那么递归搜索
(l,maxn),(maxn+1,minn-1),(minn,r) ,如果矮的牛在高的牛前面,那么我们直接用maxn-minn+1更新答案,之后递归搜索(l,minn-1),(maxn+1,r)即可。
这样的话问题就转化成了如何快速求任意一段区间内的最大最小值的位置。这是一个典型的RMQ问题,我们选择使用st表解决。既然只求最大最小值的位置,那么我们就可以不使用st表存值,这样不仅好写而且时间还短。具体的做法就是我们自定义函数来比较编号,每次比较大小结束之后记录当前区间内最大(小)值的位置即可。这样每次递归访问的时候,我们甚至可以做到O(1)。
这道题有很多地方还是非常坑的,比如说你写一个十分正确的RMQ在Lemon或者本机上运行都会导致RE,据说可能是因为递归层数过多而爆栈,这个自己本人调试也调不出来,你只会看到程序在输入所有数据之后报错。可以使用vijos代测,但是我的程序前几次提交全部TLE,结果最后采用了一个优化,就是如果递归的区间长度小于当前的答案就直接返回无需搜索。但还是不行……最后发现是因为开了全局变量的缘故,开成局部变量就过了……蒟蒻至今搞不明白是为什么。
最后上一下代码吧。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')
using namespace std;
const int N = ,M = ;
typedef long long ll;
int n,h[N],max1[N][M],min1[N][M],ans1;
int read()
{
int ans = ;
char ch,last = ' ';
ch = getchar();
while(ch < '' || ch > '')
{
if(ch == '-') ch = last;
ch = getchar();
}
while(ch >= '' && ch <= '')
{
ans *= ;
ans += ch - '';
ch = getchar();
}
if(last == '-') ans = -ans;
return ans;
}
int fmax(int c,int d)//自定义比较编号的函数
{
if(h[c] > h[d] || (h[c] == h[d] && c < d)) return c;
else return d;
}
int fmin(int c,int d)
{
if(h[c] < h[d] || (h[c] == h[d] && c > d)) return c;
else return d;
}
void ask(int l,int r)
{
if(l >= r || ans1 >= r-l+) return;//这个优化可以省很多时间
int k = log2(r-l+);//注意这里开cstdlib
int g = << k;
int maxn = fmax(max1[l][k],max1[r-g+][k]);
int minn = fmin(min1[l][k],min1[r-g+][k]);//就是这两行坑了无数次!!!
if(maxn == minn) return;
if(maxn > minn)
{
ans1 = max(ans1,maxn-minn+);//更新并递归
ask(l,minn-);
ask(maxn+,r);
return;
}
else
{
ask(l,maxn);
ask(maxn+,minn-);
ask(minn,r);
return;
}
}
int main()
{
n = read();
rep(i,,n)
{
h[i] = read();
max1[i][] = i;
min1[i][] = i;
}
int q = log2(n);
rep(j,,q)
{
for(int i = ;i+(<<j)-<=n;i++)
{
max1[i][j] = fmax(max1[i][j-],max1[i+(<<(j-))][j-]);
min1[i][j] = fmin(min1[i][j-],min1[i+(<<(j-))][j-]);
}//st表求最大最小值
}
ask(,n);
printf("%d\n",ans1);
return ;
}
奶牛排序——RMQ的更多相关文章
- 牛客假日团队赛2 H.奶牛排序
链接: https://ac.nowcoder.com/acm/contest/924/H 题意: 农夫JOHN准备把他的 N(1 <= N <= 10,000)头牛排队以便于行动.因为脾 ...
- BZOJ2815:[ZJOI2012]灾难(拓扑排序,LCA)
Description 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过 ...
- POJ -3190 Stall Reservations (贪心+优先队列)
http://poj.org/problem?id=3190 有n头挑剔的奶牛,只会在一个精确时间挤奶,而一头奶牛需要占用一个畜栏,并且不会和其他奶牛分享,每头奶牛都会有一个开始时间和结束时间,问至少 ...
- USACO 2001 OPEN
第1题 绿组. 奶牛接力赛[relay] 题目描述 农夫约翰已经为一次赛跑选出了K(2≤K≤40)头牛组成了一支接力队.赛跑在农夫约翰所拥有的农场上进行,农场的编号为1到Ⅳf4≤Ⅳ< 800), ...
- POJ2376 Cleaning Shifts
题意 POJ2376 Cleaning Shifts 0x50「动态规划」例题 http://bailian.openjudge.cn/practice/2376 总时间限制: 1000ms 内存限制 ...
- POJ 2010 Moo University - Financial Aid (优先队列)
题意:从C头奶牛中招收N(奇数)头.它们分别得分score_i,需要资助学费aid_i.希望新生所需资助不超过F,同时得分中位数最高.求此中位数. 思路: 先将奶牛排序,考虑每个奶牛作为中位数时,比它 ...
- 【贪心】洛谷P1607 [USACO09FEB]庙会班车Fair Shuttle 题解
不是很容易写出正解的贪心问题. 题目描述 Although Farmer John has no problems walking around the fair to collect pri ...
- poj3171 Cleaning Shifts
传送门 题目大意 有一个大区间和n个小区间,每个小区间都有一个代价,求最少付出多少代价可以使得小区间完全覆盖大区间. 分析为了方便起见我们先将s变为2,其它的位置都对应更改以便后期处理.我们考虑以t1 ...
- 【POJ - 2376】Cleaning Shifts(贪心)
Cleaning Shifts Descriptions: 原文是English,我这就直接上Chinese了,想看原文的点一下链接哦 大表哥分配 N (1 <= N <= 25,000) ...
随机推荐
- 虚拟机centos 里tomcat的端口映射到主机 Windows里面
- openssl搭建双向认证https
http://www.barretlee.com/blog/2015/10/05/how-to-build-a-https-server/ http://blog.163.com/fangjinbao ...
- ROS之:log文件
1.log文件的位置: log file: /home/wang/.ros/log/... 1)显示隐藏文件(.文件),Ctrl+h 2)该文件夹下的文件夹是运行launch文件产生的 3)该文件夹下 ...
- rsync故障排查整理
1.客户端的错误现象:No route to host rsync服务端开启了iptables防火墙 rsync -avz /etc/hosts rsync_backup@172.16.1.41::b ...
- 春哥的nginx systemtap调试脚本简单介绍
http://card.weibo.com/article/h5/s#cid=2304185311ad2d0102v9gd&vid=0&extparam=&from=11100 ...
- ClassLoader Java中类加载出现在哪个阶段,编译期和运行期? 类加载和类装载是一样的吗
1.ClassLoader Java中类加载出现在哪个阶段,编译期和运行期? 类加载和类装载是一样的吗? :当然是运行期间啊,我自己有个理解误区,改正后如下:编译期间编译器是不去加载类的,只负责编译而 ...
- Java主线程等待所有子线程执行完毕再执行解决办法(转)
方法一: Thread.join()方法,亲测可行,thread.join()方法 Vector<Thread> ts = new Vector<Thread>(); for ...
- 【Todo】【转载】Scala中Array, List, Tuple的区别
参考了这篇文章: https://my.oschina.net/u/1034176/blog/512314 1. 在Scala 2.7中,Array.List都不能混合类型,只有Tuple可以:而在S ...
- centos7 网络不能重启问题 解决办法
cnetos7 网络不可重启 突然解决办法 参考他人处理 之前部署hadoop环境,在自己机器上安装了一台centos虚拟机,然后图省事,就克隆出三台,一台为master,另两台来作为 slave. ...
- 【翻译自mos文章】多租户中的service管理
来源于: Service Management For Multitenant (文档 ID 2009500.1) APPLIES TO: Oracle Database - Enterprise E ...