【问题描述】
奶牛在熊大妈的带领下排成了一条直队。
显然,不同的奶牛身高不一定相同……
现在,奶牛们想知道,如果找出一些连续的奶牛,要求最左边的奶牛 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,结果最后采用了一个优化,就是如果递归的区间长度小于当前的答案就直接返回无需搜索。但还是不行……最后发现是因为开了全局变量的缘故,开成局部变量就过了……蒟蒻至今搞不明白是为什么。

最后上一下代码吧。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<cstdlib>
  6. #define rep(i,a,n) for(int i = a;i <= n;i++)
  7. #define per(i,n,a) for(int i = n;i >= a;i--)
  8. #define enter putchar('\n')
  9. using namespace std;
  10. const int N = ,M = ;
  11. typedef long long ll;
  12. int n,h[N],max1[N][M],min1[N][M],ans1;
  13. int read()
  14. {
  15. int ans = ;
  16. char ch,last = ' ';
  17. ch = getchar();
  18. while(ch < '' || ch > '')
  19. {
  20. if(ch == '-') ch = last;
  21. ch = getchar();
  22. }
  23. while(ch >= '' && ch <= '')
  24. {
  25. ans *= ;
  26. ans += ch - '';
  27. ch = getchar();
  28. }
  29. if(last == '-') ans = -ans;
  30. return ans;
  31. }
  32. int fmax(int c,int d)//自定义比较编号的函数
  33. {
  34. if(h[c] > h[d] || (h[c] == h[d] && c < d)) return c;
  35. else return d;
  36. }
  37. int fmin(int c,int d)
  38. {
  39. if(h[c] < h[d] || (h[c] == h[d] && c > d)) return c;
  40. else return d;
  41. }
  42. void ask(int l,int r)
  43. {
  44. if(l >= r || ans1 >= r-l+) return;//这个优化可以省很多时间
  45. int k = log2(r-l+);//注意这里开cstdlib
  46. int g = << k;
  47. int maxn = fmax(max1[l][k],max1[r-g+][k]);
  48. int minn = fmin(min1[l][k],min1[r-g+][k]);//就是这两行坑了无数次!!!
  49. if(maxn == minn) return;
  50. if(maxn > minn)
  51. {
  52. ans1 = max(ans1,maxn-minn+);//更新并递归
  53. ask(l,minn-);
  54. ask(maxn+,r);
  55. return;
  56. }
  57. else
  58. {
  59. ask(l,maxn);
  60. ask(maxn+,minn-);
  61. ask(minn,r);
  62. return;
  63. }
  64. }
  65. int main()
  66. {
  67. n = read();
  68. rep(i,,n)
  69. {
  70. h[i] = read();
  71. max1[i][] = i;
  72. min1[i][] = i;
  73. }
  74. int q = log2(n);
  75. rep(j,,q)
  76. {
  77. for(int i = ;i+(<<j)-<=n;i++)
  78. {
  79. max1[i][j] = fmax(max1[i][j-],max1[i+(<<(j-))][j-]);
  80. min1[i][j] = fmin(min1[i][j-],min1[i+(<<(j-))][j-]);
  81. }//st表求最大最小值
  82. }
  83. ask(,n);
  84. printf("%d\n",ans1);
  85. return ;
  86. }

奶牛排序——RMQ的更多相关文章

  1. 牛客假日团队赛2 H.奶牛排序

    链接: https://ac.nowcoder.com/acm/contest/924/H 题意: 农夫JOHN准备把他的 N(1 <= N <= 10,000)头牛排队以便于行动.因为脾 ...

  2. BZOJ2815:[ZJOI2012]灾难(拓扑排序,LCA)

    Description 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过 ...

  3. POJ -3190 Stall Reservations (贪心+优先队列)

    http://poj.org/problem?id=3190 有n头挑剔的奶牛,只会在一个精确时间挤奶,而一头奶牛需要占用一个畜栏,并且不会和其他奶牛分享,每头奶牛都会有一个开始时间和结束时间,问至少 ...

  4. USACO 2001 OPEN

    第1题 绿组. 奶牛接力赛[relay] 题目描述 农夫约翰已经为一次赛跑选出了K(2≤K≤40)头牛组成了一支接力队.赛跑在农夫约翰所拥有的农场上进行,农场的编号为1到Ⅳf4≤Ⅳ< 800), ...

  5. POJ2376 Cleaning Shifts

    题意 POJ2376 Cleaning Shifts 0x50「动态规划」例题 http://bailian.openjudge.cn/practice/2376 总时间限制: 1000ms 内存限制 ...

  6. POJ 2010 Moo University - Financial Aid (优先队列)

    题意:从C头奶牛中招收N(奇数)头.它们分别得分score_i,需要资助学费aid_i.希望新生所需资助不超过F,同时得分中位数最高.求此中位数. 思路: 先将奶牛排序,考虑每个奶牛作为中位数时,比它 ...

  7. 【贪心】洛谷P1607 [USACO09FEB]庙会班车Fair Shuttle 题解

        不是很容易写出正解的贪心问题. 题目描述 Although Farmer John has no problems walking around the fair to collect pri ...

  8. poj3171 Cleaning Shifts

    传送门 题目大意 有一个大区间和n个小区间,每个小区间都有一个代价,求最少付出多少代价可以使得小区间完全覆盖大区间. 分析为了方便起见我们先将s变为2,其它的位置都对应更改以便后期处理.我们考虑以t1 ...

  9. 【POJ - 2376】Cleaning Shifts(贪心)

    Cleaning Shifts Descriptions: 原文是English,我这就直接上Chinese了,想看原文的点一下链接哦 大表哥分配 N (1 <= N <= 25,000) ...

随机推荐

  1. jquery 禁用/启用滚动条

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 标准IO函数以及基本知识点总结

    什么是标准IO呢?有哪些特点? 标准IO是标准c库提供的对文件操作的函数接口.他的特点是:1 带缓存,2 大部分都调用系统接口函数实现.(c库就是一种实现好的函数接口,作用是屏蔽下层细节.提供上层接口 ...

  3. iOS开发 检测版本更新

    iOS开发 检测版本更新的实现 苹果给了我们一个接口,能根据应用id请求一些关于应用的信息.我们可以根据返回的信息,来判断版本是否和应用的版本一致,如果不一致,那么就出现新的版本了.这时,就需要向用户 ...

  4. python各种类型转换

    python各种类型转换 学习了:https://blog.csdn.net/shanliangliuxing/article/details/7920400 https://blog.csdn.ne ...

  5. docker下用keepalived+Haproxy实现高可用负载均衡集群

    启动keepalived后宿主机无法ping通用keepalived,报错: [root@localhost ~]# ping 172.18.0.15 PING () bytes of data. F ...

  6. [Testing] Static Analysis Testing JavaScript Applications

    The static code analysis and linting tool ESLint is the de-facto standard for linting JavaScript pro ...

  7. apache多网站配置

    前言  虽说apache安装好后给了我们一个默认的一个网站.并且我们还能够将这个默认的网站改动成我们自己的网站.可是这似乎还不能全然满足我们的须要,由于当我们要在本机上开发(phpWeb)或者測试另外 ...

  8. js中对arry数组的各种操作小结 瀑布流AJAX无刷新加载数据列表--当页面滚动到Id时再继续加载数据 web前端url传递值 js加密解密 HTML中让表单input等文本框为只读不可编辑的方法 js监听用户的键盘敲击事件,兼容各大主流浏览器 HTML特殊字符

    js中对arry数组的各种操作小结   最近工作比较轻松,于是就花时间从头到尾的对js进行了详细的学习和复习,在看书的过程中,发现自己平时在做项目的过程中有很多地方想得不过全面,写的不够合理,所以说啊 ...

  9. AIX下RAC搭建 Oracle10G(二)主机配置

    AIX下RAC搭建系列 AIX下RAC搭建 Oracle10G(二)主机配置 环境 节点 节点1 节点2 小机型号 IBM P-series 630 IBM P-series 630 主机名 AIX2 ...

  10. CycleViewPager

    https://github.com/zhaozhentao/CycleViewPager