题意

link(more:SPOJ1805

如图,在水平线上有 \(n(n\leqslant10^5)\) 个宽度为 1 ,高度为 \(h(0\leqslant h\leqslant10^9)\) 的矩形,求包含于其中的最大子矩形面积。

例: \(h=\{2,1,4,5,1,3,3\};S_{max}=S_{阴影}\)

思路

朴素

首先简单模拟过程,可知当前高度受 \(h_i\) 的限制,以此向左右尽量扩边界 \(l_i,r_i\) ,得到当高度为 \(h_i\) 时的最大子矩形,在图中表现为:

不难看出,当 \(l_i,r_i\) 遇到第一个高度比 \(h_i\) 低的矩形时,就达到了最大边界。

∴易想到枚举所有矩形,每次向左右枚举得到 \(l_i,r_i\) 算出当前面积。

但该算法最坏复杂度显然达到 \(O(n^2)\) ,妥妥的超时。

优化

那么就必须得用 \(O(1)\) 的时间得到 \(l_i,r_i\) 才能降到 \(O(n)\) 通过此题。

由于求 \(l_i,r_i\) 是对称的,接下来考虑一边 \(l_i\) :

我们从左往右观察每个子矩形 \(l_i\) 的推导过程,若 \(h_j<h_i\) ,那么前 \(k(k\in[1,j-1])\) 个对于 求当前子矩形边界 就没有任何意义了。

继续推广,我们同时要考虑到后 \(k(k\in[i+1,n])\) 个矩形中可能有 \(h_k<h_i\) 的情况。

也就是说,如果全局性考虑的话,在前 \(k(k\in[1,j-1])\) 个其中 \(h_k<h_j\) 的矩形 仍是有潜力成为边界的 ,就需要保留。


基于上述所说,我们可以这样考虑:

显然要把 \(h_i\) 放入一个数据结构里处理,在尾端作插入和删除操作。(就是栈啦)

现在考虑一个中间状态,将要进来 \(h_i\) ,前面已经放入 \(k\) 个矩形了。

我们要找第一个 \(h_j<h_i(j\in[1,k])\) ,那么在栈中就可以把\(h_j\geqslant h_i\) 的删掉,模拟一下样例:

可知,在栈中,矩阵高度保持 单调性 ,且是单调递增,这就是 单调栈

有了单调性,就可以 \(O(1)\) 的时间得到 \(l_i\) .

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,h[N],l[N],r[N],s[N],t;
int main()
{
while(cin>>n,n)
{
for(int i=1;i<=n;i++) cin>>h[i];
h[0]=h[n+1]=-1;//边界
t=0;
s[t]=0;//先存进边界编号
for(int i=1;i<=n;i++)
{
while(h[s[t]]>=h[i]) t--;
l[i]=s[t];
s[++t]=i;
}
t=0;
s[t]=n+1;
for(int i=n;i>=1;i--)
{
while(h[s[t]]>=h[i]) t--;
r[i]=s[t];
s[++t]=i;
}
ll ans=0;
for(int i=1;i<=n;i++)
ans=max(ans,(ll)h[i]*(r[i]-l[i]-1));
cout<<ans<<endl;
}
return 0;
}

总结

单调栈思想:及时排除不可能的选项,保持策略集合的高度有效性和秩序性。

[0x11] 131.直方图中最大的矩形【单调栈】的更多相关文章

  1. hdu1506 直方图中最大的矩形 单调栈入门

    hdu1506 直方图中最大的矩形 单调栈入门 直方图是由在公共基线对齐的矩形序列组成的多边形.矩形具有相同的宽度,但可能具有不同的高度.例如,左侧的数字显示了由高度为2,1,4,5,1,3,3的矩形 ...

  2. AcWing:131. 直方图中最大的矩形(贪心 + 单调栈)

    直方图是由在公共基线处对齐的一系列矩形组成的多边形. 矩形具有相等的宽度,但可以具有不同的高度. 例如,图例左侧显示了由高度为2,1,4,5,1,3,3的矩形组成的直方图,矩形的宽度都为1: 通常,直 ...

  3. [LeetCode] Largest Rectangle in Histogram 直方图中最大的矩形

    Given n non-negative integers representing the histogram's bar height where the width of each bar is ...

  4. [LeetCode] 84. Largest Rectangle in Histogram 直方图中最大的矩形

    Given n non-negative integers representing the histogram's bar height where the width of each bar is ...

  5. [leetcode]84. Largest Rectangle in Histogram直方图中的最大矩形

    Given n non-negative integers representing the histogram's bar height where the width of each bar is ...

  6. 51nod 1102 面积最大的矩形 (单调栈)

    链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1102 思路: 首先介绍下单调栈的功能:利用单调栈,可以找到从左/ ...

  7. [51nod1102]面积最大的矩形(单调栈||预处理)

    题意:求序列上某区间最小值乘区间长度的最大值. 解题关键:很早就在<挑战程序设计竞赛>中见过了,单调栈模板题,注意弹栈时如何处理后面的元素. 法一:单调栈 #include<bits ...

  8. Leetcode84. 柱状图中最大的矩形(单调栈)

    84. 柱状图中最大的矩形 前置 单调栈 做法 连续区间组成的矩形,是看最短的那一块,求出每一块左边第一个小于其高度的位置,右边也同理,此块作为最短限制.需要两次单调栈 单调栈维护递增区间,每次不满足 ...

  9. hdoj - 1506 直方图中最大的矩形

    Problem Description A histogram is a polygon composed of a sequence of rectangles aligned at a commo ...

随机推荐

  1. PHP全栈开发(六):PHP与HTML页面交互

    之前我们在HTML表单学习这篇文章里面创建了一个HTML页面下的表单. 这个表单是用户用来输入数据的 具体代码如下 <!DOCTYPE html> <html> <hea ...

  2. POJ1651 Multiplication Puzzle (区间DP)

    这道题的妙处在于把原问题看成矩阵连乘问题,求这些矩阵相乘的最小乘法次数,比如一个i*k矩阵乘一个k*j的矩阵,他们的乘法次数就是i*k*j (联想矩阵乘法的三层循环),题目说的取走一张牌,类似于矩阵相 ...

  3. 洛谷P4630 [APIO2018] Duathlon 铁人两项 (圆方树)

    圆方树大致理解:将每个点双看做一个新建的点(方点),该点双内的所有点(圆点)都向新建的点连边,最后形成一棵树,可以给点赋予点权,用以解决相关路径问题. 在本题中,方点点权赋值为该点双的大小,因为两个点 ...

  4. LcdTools如何通过PX01把EDP屏的EDID拷贝出来

    PX01点EDP屏在上电过程会自动读取屏EDID,怎么把EDP EDID值拷贝出来呢? 在上电时序函数调用SetEdidRdShowEn(ON)指令开启EDID值读取显示功能.如下图 通过上述操作开机 ...

  5. 使用dotnet-monitor sidecar模式 dump docker运行的dotnet程序.

    前情概要 随着容器和云技术的发展, 大量的应用运行在云上的容器中, 它们的好处是毋庸置疑的, 例如极大的提高了我们的研发部署速度, 快速的扩缩容等等, 但是也存在一些小小的问题, 例如难以调试. 基于 ...

  6. Vue实现离开页面二次确认

    在项目开发中遇到用户编辑内容后未保存推出编辑页面时需要提示用户"当前数据未保存,是否退出",实际开发中利用window.onbeforeunload方法与vue.$on方法在upd ...

  7. webpack -- element-ui 的按需引入

    简单说明原理: 使用babel-plugin-component实现按需引入.打包.将webpack配置成多入口,保证最终打包的目录结构符合babel-plugin-component插件的要求,实现 ...

  8. 【安装文档】TRex流量分析仪保姆级安装指南--基于VMware虚拟机(ubantu18.04@Intel 82545EM)

    前言 既然你已经知道TRex并尝试搜索它的安装教程,这意味着你有一定的基础知识(至少知道自己需要什么).因此本文对于TRex的介绍部分会偏少 本次主要为TRex安装过程的一次记录(版本为v3.0.0) ...

  9. <六>指向类成员的指针

    指向类成员(成员变量和成员方法)的指针 1:定义一个指针指向类的普通成员变量 示例代码1 点击查看代码 class Test2{ public: int ma; static int mb; void ...

  10. 配置MSTP功能示例

    组网需求 在一个复杂的网络中,网络规划者由于冗余备份的需要,一般都倾向于在设备之间部署多条物理链路,其中一条作主用链路,其他链路作备份.这样就难免会形成环形网络,若网络中存在环路,可能会引起广播风暴和 ...