题意

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. POJ3237 Tree (树链剖分)

    通过打懒标记实现区间取反,和线段树基本操作都差不多. 本题还是一道边权化为点权的问题. 200行巨长代码: 1 #include<cstdio> 2 #include<cstring ...

  2. 基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成

    在前面随笔<基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理>中我们已经介绍过,对于相关的业务表的界面代码,我们已经尽可能把不同的业务逻辑 ...

  3. Java中的名称命名规范

    包名:多单词组成时所有字母都小写:xxxyyyzzz 类名.接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz 变量名.方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首 ...

  4. 方法的重载(overload)

    1.定义:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可. "两同一不同":同一个类.相同方法名 参数列表不同:参数个数不同,参数类型不同 2.举 ...

  5. 1.MongoDB之服务启动

    1. 编写docker-compose.yaml文件 version: "3" services: mongo: image: mongo:4.2.6 ports: - 27017 ...

  6. wampServer配置WWW根目录遇到的坑

    直接在官网下载之后开始安装,一切正常 打开使用,一切正常 设置WWW目录.坑了一波 按照的都是百度上的教程,设置httpd.conf 这里配置之后网页访问127.0.0.1 还是localhost都还 ...

  7. python关于Django搭建简单博客项目(教程)

    由于csdn各种django blog博文都有或多或少的bug,所以我决定自己写一篇,先附上教程,详解在另一篇博文里,为了便于大家复制粘贴,本文代码尽量不使用图片. 源代码及解析文章请在我的githu ...

  8. .NET Conf 2022 &ndash; 11 月 8 日至 10 日

    .NET Conf 2022 下周就正式开启了,时间是美国时间的 11月8日至10日..NET Conf 2022是一个免费的,为期三天的, 虚拟开发人员活动提供多种实时会话,其中包括来自社区和 .N ...

  9. Day13 note

    super注意点: 1.super调用父类的构造方法,必须在构造方法的第一行 2.super必须只能出现在子类的方法或者构造方法中 3.super和this不能同时调用构造方法对比this: 1.代表 ...

  10. Flask框架:运用Ajax轮询动态绘图

    Ajax是异步JavaScript和XML可用于前后端交互,在之前<Flask 框架:运用Ajax实现数据交互>简单实现了前后端交互,本章将通过Ajax轮询获取后端的数据,前台使用echa ...