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 ...
随机推荐
- IHttpHandler的那些事
写在前面 从上家公司离职,在家休息,闲着无聊,觉得还是有必要将IHttpHanlder的内容,做一个总结.发现在写demo的过程中,总觉得有点生疏了,项目中很少使用自定义的类来实现该接口.当然,一般处 ...
- BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第10章节--SP2013中OAuth概览 应用程序验证
BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第10章节--SP2013中OAuth概览 应用程序验证 既然你懂得了什么是应用程序身份.而且知道怎样在SP中创建和设置 ...
- 浅谈AngularJS的$parse服务
$parse 作用:将一个AngularJS表达式转换成一个函数 Usage$parse(expression) arguments expression:需要被编译的AngularJS语句 retu ...
- POJ3187 Backward Digit Sums 【暴搜】
Backward Digit Sums Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4487 Accepted: 25 ...
- Android Shape 形状
Shape继承体系: Shape (android.graphics.drawable.shapes) ----PathShape (android.graphics.drawable.shapes) ...
- Ownerdrawn ComboBox
[ToolboxBitmap(typeof(ComboBox))] class ComboBoxEx : ComboBox { public ComboBoxEx() { this.DrawMode ...
- 0069 如何在Intellij IDEA中查看Spring MVC项目的所有请求与处理方法的映射列表
@RequestMapping注解分散于Controller中,如何在一个列表中看到所有的请求呢,比如下面这样: File-->Project Structure-->Modules--& ...
- 绕过IE10直接安装VS2013
参考资料:http://blog.163.com/qimo601%40126/blog/static/1582209320143354446462/ 这SB设定我就懒得说了,安个IE10要安装N多WI ...
- std::string与output-operator"<<"的兼容问题
经查阅资料得知,“在某些编译器下std::string,需要使用c_str()才能作为output-operator "<<" 的参数” std::string tit ...
- HDFS设计思路,HDFS使用,查看集群状态,HDFS,HDFS上传文件,HDFS下载文件,yarn web管理界面信息查看,运行一个mapreduce程序,mapreduce的demo
26 集群使用初步 HDFS的设计思路 l 设计思想 分而治之:将大文件.大批量文件,分布式存放在大量服务器上,以便于采取分而治之的方式对海量数据进行运算分析: l 在大数据系统中作用: 为各类分布式 ...