题目大意

给出一个柱形图中柱子的高度,每个柱子的宽度为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 单调栈的更多相关文章

  1. POJ 2559 Largest Rectangle in a Histogram (单调栈或者dp)

    Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15831 ...

  2. BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 8748  Solved: 3835[Submi ...

  3. BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]

    4453: cys就是要拿英魂! Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 90  Solved: 46[Submit][Status][Discu ...

  4. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2326  Solved: 1054[Submit][Status ...

  5. poj 2559 Largest Rectangle in a Histogram - 单调栈

    Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19782 ...

  6. bzoj1510: [POI2006]Kra-The Disks(单调栈)

    这道题可以O(n)解决,用二分还更慢一点 维护一个单调栈,模拟掉盘子的过程就行了 #include<stdio.h> #include<string.h> #include&l ...

  7. BZOJ1057[ZJOI2007]棋盘制作 [单调栈]

    题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的 ...

  8. 洛谷U4859matrix[单调栈]

    题目描述 给一个元素均为正整数的矩阵,上升矩阵的定义为矩阵中每行.每列都是严格递增的. 求给定矩阵中上升子矩阵的数量. 输入输出格式 输入格式: 第一行两个正整数n.m,表示矩阵的行数.列数. 接下来 ...

  9. POJ3250[USACO2006Nov]Bad Hair Day[单调栈]

    Bad Hair Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17774   Accepted: 6000 Des ...

随机推荐

  1. 公有/私有/保护继承、overload/overwrite/override之间的区别

    一.继承 C++很重要的一个特征就是代码重用.在C语言中重用代码的方式就是拷贝代码.修改代码.C++可以用继承或组合的方式来重用.通过组合或继承现有的的类来创建新类,而不是重新创建它们. 继承是使用已 ...

  2. javascript sort方法容易犯错的地方

    sort方法用来对数组排序非常方便.但是sort(func)这个func参数的构造却很容易混淆. sort判断func的返回值是判断正负,而不是ture和false.所以务必保证返回值要么负数要么正数 ...

  3. Mysql 数据库数值类型详解

    MySQL 支持所有标准SQL 中的数值类型,其中包括严格数值类型(INTEGER.SMALLINT.DECIMAL 和NUMERIC),以及近似数值数据类型(FLOAT.REAL 和DOUBLE P ...

  4. unity, mono断点

    在unity编辑器中点运行后,如果直接在mono中打断点是不起作用的,需要再点击mono的run按钮,此时弹出Attach to Process对话框,如图: 选中其中的Unity Editor (U ...

  5. Cookie/Session编码

    Unicode编码:保存中文 中文与英文字符不同,中文属于Unicode字符,在内存中占4个字符,而英文属于ASCII字符,内存中只占2个字节.Cookie中使用Unicode字符时需要对Unicod ...

  6. UIApplication深入学习

    多时候,我们不需要关心这个类,我们很少继承这个类,偶尔会调用这个类的api来实现一些功能,但是不可否认,这个类是iOS编程中很重要的一个概念.UIApplication的核心作用是提供了iOS程序运行 ...

  7. NSString (NSStringPathExtensions)

    转自:http://linwwwei.iteye.com/blog/1407520 + (NSString *)pathWithComponents(NSArray *)components 根据co ...

  8. 关于Safe DOG的文件上传bypass

    Author:倾旋payloads@aliyun.com本文由科拉实验室成员倾旋原创文章 Part 1 分析 此文主要研究安全狗的数据包分析功能,由于很多人都认为安全狗是通过正则去匹配的,那么暂且那么 ...

  9. Qt 中彩色图像转换为灰度图

    近期在做几个图像处理相关的项目.里面有一个操作就是须要先将彩色图像转换为灰度图像. QImage 有一个convertToFormat方法.最開始一直用这个函数来实现. 可是今天细致看了看,发现这个函 ...

  10. lucene 内存索引存储每个field里内容的相关代码

    相关的类调用关系 DocumentsWriterPerThread ——>DocFieldProcessor   DocumentsWriterPerThread里的consumer对象(类型是 ...