☆ [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 ...
随机推荐
- 52abp框架asp.net core & Angular快速开发实战视频教程
课程标题 52abp框架asp.net core & Angular全栈开发实战视频课程 课程简介 从零开始学 52ABP企业开发框架,企业项目是如何开发和技术选型,代码如何管理,团队协同开发 ...
- Jmeter(三十七)循环控制器+交替控制器+事务控制器 完美实现接口字段参数化校验
我们在做接口自动化的时候,常常因为无法灵活的的校验接口字段而烦恼.不能自动校验接口字段的脚本,也就不能称之为接口自动化.因此,我设计了一套组合式的控制器,可以完美的解决这个问题 1:首先我们需要在本地 ...
- easyui datagrid 相关取数据总结
easyui 中datagrid$('#dg').datagrid('getSelected');返回第一个被选中的行或如果没有选中的行则返回null.$('#dg').datagrid('getSe ...
- Gym 101873F Plug It In(二分图匹配)
题目链接:http://codeforces.com/gym/101873/problem/F 题意:有n个插孔,m个机器,和一个插板,一个插孔可以连接一个机器,插板可以使一个插孔连接三个机器,找到最 ...
- [2019BUAA软工助教]结对编程 - 小结
[2019BUAA软工助教]结对编程 - 小结 一.评分规则 博客 博客共五十分 序号 要求 分值 1 在文章开头给出Github项目地址 1 2 在开始实现程序之前,在下述PSP表格记录下你估计将在 ...
- Java对象的创建、内存布局和访问定位
在Java运行时数据区中,我们知道了虚拟机内存的概况,本文介绍虚拟机内存中的数据的其它细节,如对象如何创建.如何布局以及如何访问. 基于实用的原则,这里以HotSpot虚拟机和常用的内存区域Java堆 ...
- 使用 Drools 和 JPA & Drools show case in docker hub
使用 Drools 和 JPA 实现持续的实时数据分析https://www.ibm.com/developerworks/cn/java/j-drools5/index.html Drools - ...
- linuxmint 搜狗输入法安装
1.下载搜狗输入法linux安装包 2.进入安装包目录终端键入 dpkg -i [软件包名字] 3.设置语言选项中选择fcitx 4.重启电脑
- CLOUD设置过滤方案不共享
1.打开BOS,找到应用框架-动态表单-过滤方案另存 2.找到共享给他人,把可见性全部去掉
- Hbase 架构体系
有2个节点进程,一个是master,另一是regionserver.
