poj_2559 单调栈
题目大意
给出一个柱形图中柱子的高度,每个柱子的宽度为1,柱子相邻。求出柱形图中可能形成的矩形的最大面积。
题目分析
以每个柱子(高度为h[i])为中心,向两边延展求出以该h[i]为高度的矩形的最大宽度w[i]。h[i]*w[i]得到以该柱子为中心的最大矩形面积,遍历一遍之后取最大值即可。
关键在于求出以柱子i为中心的两边延展的矩形最大宽度。先考虑柱子i延伸到左边的最大距离:坐标p不断左移,直到h[p] < h[i],然后i - p即为柱子向左延伸的最大长度。如果直接这么做,复杂度为O(n^2)。显然,如果h[i] > h[i-1],则left_width[i] 必定为 left_width[i-1] +1, 若查找完left_width[i-1],则可以通过这个性质直接知道left_width[i]。显然,直接查找存在重复。
观察发现,对于当前点i和它之前的距离它最近的满足h[k] < h[i]的点k,若要获得i向左延伸的最大距离,只需要知道k,而k和i中间的那些点j不需要被查询(是否满足h[i] >= h[j])。于是,我们只保存k和i这样的点,以便在查找的时候跳过k和i中间的那些点,于是可以使用单调栈来实现。
单调栈中存放元素(点的索引,点的高度),若当前点的高度大于栈顶元素点的高度,则入栈;否则,弹栈,直到当前点的高度大于栈顶元素的高度,然后入栈。此时,当前点i的left_width[i] = i - 入栈之前的栈顶元素的索引。
同理,利用单调栈查找向右延伸的最大长度。
感觉:单调栈/单调队列经常用在需要从某个点i向回查找,且直接查找会出现冗余访问导致复杂度为O(n^2)的问题上。在查找的时候考虑不进行往回找,而是利用数据的单调性质一遍查找,则可将复杂度降为O(n)
实现(c++)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#define MAX_NUM 100005
int gStack[MAX_NUM][2];
int gHeight[MAX_NUM];
int gWidth[MAX_NUM][2];
long long int GetMax(int n){
memset(gWidth, 0, sizeof(gWidth));
int top = -1;
int i = 0;
while (i < n){
while (top >= 0 && gStack[top][1] >= gHeight[i]){
top--;
}
if (top >= 0)
gWidth[i][0] = i - gStack[top][0];
else{
gWidth[i][0] = i + 1;
}
top++;
gStack[top][0] = i;
gStack[top][1] = gHeight[i];
i++;
}
i = n - 1;
top = -1;
while(i >= 0){
while (top >= 0 && gStack[top][1] >= gHeight[i]){
top--;
}
if (top >= 0){
gWidth[i][1] = gStack[top][0] - i;
}
else{
gWidth[i][1] = n - i;
}
top++;
gStack[top][0] = i;
gStack[top][1] = gHeight[i];
i--;
}
long long int max = 0;
for (int i = 0; i < n; i++){
long long int tmp = (long long int) (gWidth[i][0] + gWidth[i][1] - 1)*gHeight[i];
max = max > tmp ? max : tmp;
}
return max;
}
int main(){
int n;
while(scanf("%d", &n)){
if (n == 0){
break;
}
for (int i = 0; i < n; i++){
scanf("%d", gHeight + i);
}
long long int max = GetMax(n);
printf("%lld\n", max);
}
return 0;
}
poj_2559 单调栈的更多相关文章
- POJ 2559 Largest Rectangle in a Histogram (单调栈或者dp)
Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15831 ...
- BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 8748 Solved: 3835[Submi ...
- BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]
4453: cys就是要拿英魂! Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 90 Solved: 46[Submit][Status][Discu ...
- BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2326 Solved: 1054[Submit][Status ...
- poj 2559 Largest Rectangle in a Histogram - 单调栈
Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19782 ...
- bzoj1510: [POI2006]Kra-The Disks(单调栈)
这道题可以O(n)解决,用二分还更慢一点 维护一个单调栈,模拟掉盘子的过程就行了 #include<stdio.h> #include<string.h> #include&l ...
- BZOJ1057[ZJOI2007]棋盘制作 [单调栈]
题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的 ...
- 洛谷U4859matrix[单调栈]
题目描述 给一个元素均为正整数的矩阵,上升矩阵的定义为矩阵中每行.每列都是严格递增的. 求给定矩阵中上升子矩阵的数量. 输入输出格式 输入格式: 第一行两个正整数n.m,表示矩阵的行数.列数. 接下来 ...
- POJ3250[USACO2006Nov]Bad Hair Day[单调栈]
Bad Hair Day Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 17774 Accepted: 6000 Des ...
随机推荐
- unity, Root Motion
(引自:http://tieba.baidu.com/p/4323644080) 然后详细看了下这个文档:http://docs.unity3d.com/Manual/RootMotion.html ...
- 玩转Linux文件描述符和重定向
本文介绍linux中文件描述符与重定向的相关知识,文件描述符是与文件输入.输出相关联的整数,它们用来跟踪已打开的文件.有需要的朋友参考下. 原文出处:http://www.jbxue.com/arti ...
- android.animation(5) - PropertyValuesHolder与Keyframe(转)
前几篇给大家讲了ValueAnimator.ObjectAnimator的知识,讲解了它们ofInt(),ofFloat(),ofObject()函数的用法.细心的同学可能会注意到,ValueAnim ...
- CSS3 Flex布局(伸缩布局盒模型)学习
CSS3 Flex布局(伸缩布局盒模型)学习 转自:http://www.xifengxx.com/web-front-end/1408.html CSS2定义了四种布局:块布局.行内布局.表格布局盒 ...
- maven 中使用jstl 错误解决
maven 中使用jstl表达式中出现如上错误.原因: 导入jstl 的jar包,却没有在pom文件中添加jstl相关的jar依赖项. <!--jstl表达式--> <depende ...
- 【转】搞清楚LzoCodec和LzopCodec
使用LZO过程会发现它有两种压缩编码可以使用,即LzoCodec和LzopCodec,下面说说它们区别: LzoCodec比LzopCodec更快, LzopCodec为了兼容LZOP程序添加了如 b ...
- You-Get 视频下载工具 Python命令行下载工具
You-Get 是一个命令行工具, 用来下载各大视频网站的视频, 是我目前知道的命令行下载工具中最好的一个, 之前使用过 youtube-dl, 但是 youtube-dl 吧, 下载好的视频是分段的 ...
- jquery 给表格tbody t 加事件
jquery给所有td加事件 $('#erji_list_table').on('click','td', function(){ $('#yuan_content').slideToggle(&qu ...
- 解决将Ubuntu下导出的requirements.txt到Centos服务器上面出现pkg-resource的版本为0.0.0
最直接有效的方法: 原因:
- js 内存泄漏
在javascript中,我们很少去关注内存的管理.我们创建变量,使用变量,浏览器关注这些底层的细节都显得很正常. 但是当应用程序变得越来越复杂并且ajax化之后,或者用户在一个页面停留过久,我们可能 ...