☆ [POJ2559] Largest Rectangle in a Histogram 「单调栈」
类型:单调栈
传送门:>Here<
题意:给出若干宽度相同的矩形的高度(条形统计图),求最大子矩形面积
解题思路
单调栈的经典题
显然,最终的子矩形高度一定和某一个矩形相等(反证)。因此一个暴力的做法就是枚举每一个矩形,然后往两边扩散。在它左侧找到第一个高度比它小的,右侧也一样。则可以求出最大可扩散宽度,乘上高度即可以更新答案。复杂度$O(n^2)$
如果说要优化刚才的算法,也就可以优化寻找最大可扩散宽度的速度
让每一个矩形依次入栈,保存两个关键字:矩形高度,其最大左扩散宽度。保证栈内的矩形高度单调递增
我们可以得到结论:目前栈内的一个矩形$u$,在原图中从$u$开始一直到栈顶所在的矩形,高度一定都比$u$高。这就是为什么我们不需要统计栈内矩形的最大右扩散宽度,因为最大右扩散宽度就是栈顶
再回忆一下最大左扩散宽度的意义,是在它左侧的高度大于它的矩形们。这让我们又得出一个结论:目前栈内的一个矩形$u$,如果它的最大左扩散宽度大于$1$,则这些它所能扩散到的矩形一定都不在栈中。这也很容易发现,因为栈是单调递增的。或者,我们可以得到一个更形象的结论:栈内连续的两个矩形$u,v$,如果在原图中他们之间有矩形,那么这些矩形一定都高于$u,v$
因此刚才我们所说的最大左扩散宽度,其实等同于在原图中,它到栈中上一个矩形之间相隔了多少矩形
当一个新的矩形进来的时候,它会弹走若干个矩形。而栈内一个矩形实际上代表着原图中一段矩形。因此可以说是弹走了几段矩形。但是这些被弹走的矩形只不过出栈,在原图中并不会消失。因此他们所代表的的宽度不应当消失,所以我们将他们累积在新进来的这个矩形上。这也非常符合事实——这个新的矩形之所以能弹走这若干个矩形是因为自己比他们矮,因此都可以扩散到。换句话说,被弹走的这一系列矩形最多只能向右扩散到这个新矩形,因此留着它们就没有意义了
而对于任何一个要出栈的矩形,我们需要统计由它的高度所能扩散出去的最大子矩形面积。由于它的最大左扩散宽度已知,唯一需要知道的就是它的最大右扩散宽度。那么由于它在栈里,它的最大右扩散宽度也就是从它一直到最早先的栈顶之间的宽度。因此我们只需要在弹栈的过程中一路累积每个出栈矩形的最大左扩散宽度,加起来就是这一段宽度了。
另外,如果处理完了最后一个矩形以后栈依然有剩余,则应当弹完并更新答案
保证了每个矩形入栈以及出栈恰好一次,在正确性显然的条件下,复杂度$O(n)$
Code
/*By DennyQi 2018.8.18*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define r read()
#define Max(a,b) (((a)>(b)) ? (a) : (b))
#define Min(a,b) (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
#define int ll
const int MAXN = ;
const int INF = ;
inline int read(){
int x = ; int w = ; register int c = getchar();
while(c ^ '-' && (c < '' || c > '')) c = getchar();
if(c == '-') w = -, c = getchar();
while(c >= '' && c <= '') x = (x<<) + (x<<) + c - '', c = getchar();return x * w;
}
int N,H,top,cnt,ans;
int h[MAXN],w[MAXN];
#undef int
int main(){
#define int ll
for(;;){
N=r;
if(!N) break;
top = ;
ans = ;
for(int i = ; i <= N; ++i){
H=r;
if(!top || H > h[top]){
h[++top] = H;
w[top] = ;
}
else{
cnt = ;
while(top > && H <= h[top]){
cnt += w[top];
ans = Max(ans, h[top] * cnt);
--top;
}
h[++top] = H;
w[top] = cnt+;
}
}
cnt = ;
while(top > ){
cnt += w[top];
ans = Max(ans, h[top] * cnt);
--top;
}
printf("%lld\n", ans);
}
return ;
}
☆ [POJ2559] Largest Rectangle in a Histogram 「单调栈」的更多相关文章
- poj2559 Largest Rectangle in a Histogram(单调栈)
Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base l ...
- POJ2559 Largest Rectangle in a Histogram (单调栈
Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26012 ...
- poj 2559 Largest Rectangle in a Histogram (单调栈)
http://poj.org/problem?id=2559 Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 6 ...
- 题解报告:poj 2559 Largest Rectangle in a Histogram(单调栈)
Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base l ...
- HDU-1506 Largest Rectangle in a Histogram【单调栈】
Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base l ...
- Largest Rectangle in a Histogram【单调栈模板】
Largest Rectangle in a Histogram 题目链接(点击)来源poj 2559 A histogram is a polygon composed of a sequence ...
- hdu_1506:Largest Rectangle in a Histogram 【单调栈】
题目链接 对栈的一种灵活运用吧算是,希望我的注释写的足够清晰.. #include<bits/stdc++.h> using namespace std; typedef long lon ...
- POJ 2559 Largest Rectangle in a Histogram(单调栈)
[题目链接] http://poj.org/problem?id=2559 [题目大意] 给出一些宽度为1的长方形下段对其后横向排列得到的图形,现在给你他们的高度, 求里面包含的最大长方形的面积 [题 ...
- HDU 1506 Largest Rectangle in a Histogram(单调栈、笛卡尔树)
题意:给定n个连续排列的矩形的高,矩形的宽都为1.问最大矩形覆盖. 例如:n = 7,h[i] = (2 1 4 5 1 3 3),最大覆盖为8. Sample Input 7 2 1 4 5 1 3 ...
随机推荐
- [程序员的业余生活]一周读完《高效能人士的七个习惯》Day1:这是不是一碗鸡汤?
提出问题 今天突然想聊聊最近对职场的一些感悟. 这段时间,小端一直在思考一个问题:作为一个程序员,怎么才能成为团队的核心? 还记得刚入职场那几年,小端一直觉得,技术过硬,经验丰富,敢打敢拼,就是答案. ...
- PS调出冷绿色电影画面风格
原图 一.按照惯例先磨皮,我修照片的习惯是,先拉一层色阶,使直方图平均分配,画面会显得没那么灰,当然,这只是个人喜好,先加后加都没所谓. 二.由于脸部的亮度不够,显得有点脏.所以这一步主要是通过拉曲线 ...
- threading模块,python下的多线程
一.GIL全局解释器锁 In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple nativ ...
- (关于数据传输安全)SSH协议
这里说的不是java的SSH框架,是1995年,芬兰学者Tatu Ylonen设计的SSH协议. 有计算机网络基础的同学都知道,在网上传输的数据是可以被截取的.那么怎样才能获得安全? 一.春点行话 电 ...
- noode inquirer
一. 由于交互的问题种类不同,inquirer为每个问题提供很多参数: type:表示提问的类型,包括:input, confirm, list, rawlist, expand, checkbox, ...
- java程序员一些初中级面试题(数据库部分)
说出一些数据库优化方面的经验? 1.从JDBC编程的角度讲,用PreparedStatement一般来说比Statement性能高,因为在使用时,SQL语句被预编译并存储在PreparedStatem ...
- VUE.JS 使用axios数据请求时数据绑定时 报错 TypeError: Cannot set property 'xxxx' of undefined 的解决办法
正常情况下在data里面都有做了定义 在函数里面进行赋值 这时候你运行时会发现,数据可以请求到,但是会报错 TypeError: Cannot set property 'listgroup' of ...
- liunx 运维知识四部分
一. 权限介绍及文件权限测试 二. 目录权限测试 三. 默认控制权限umask 四. chown修改属性和属组 五. 网站安全权限介绍 六. 隐藏属性介绍 七. 特殊权限s 八. 特殊权限t 九. 用 ...
- python之路--基础数据类型的补充与深浅copy
一 . join的用法 lst =['吴彦祖','谢霆锋','刘德华'] s = '_'.join(lst) print(s) # 吴彦祖_谢霆锋_刘德华 # join() "*" ...
- js的常用文档对象,document
1.document的概念:window的子对象,由于DOM对象模型的默认对象就是window,因此Window对象中的方法和子对象不需要通过Window来引用. - 2.document的组成:属性 ...
