[0x11] 131.直方图中最大的矩形【单调栈】
题意
如图,在水平线上有 \(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.直方图中最大的矩形【单调栈】的更多相关文章
- hdu1506 直方图中最大的矩形 单调栈入门
hdu1506 直方图中最大的矩形 单调栈入门 直方图是由在公共基线对齐的矩形序列组成的多边形.矩形具有相同的宽度,但可能具有不同的高度.例如,左侧的数字显示了由高度为2,1,4,5,1,3,3的矩形 ...
- AcWing:131. 直方图中最大的矩形(贪心 + 单调栈)
直方图是由在公共基线处对齐的一系列矩形组成的多边形. 矩形具有相等的宽度,但可以具有不同的高度. 例如,图例左侧显示了由高度为2,1,4,5,1,3,3的矩形组成的直方图,矩形的宽度都为1: 通常,直 ...
- [LeetCode] Largest Rectangle in Histogram 直方图中最大的矩形
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- [LeetCode] 84. Largest Rectangle in Histogram 直方图中最大的矩形
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- [leetcode]84. Largest Rectangle in Histogram直方图中的最大矩形
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- 51nod 1102 面积最大的矩形 (单调栈)
链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1102 思路: 首先介绍下单调栈的功能:利用单调栈,可以找到从左/ ...
- [51nod1102]面积最大的矩形(单调栈||预处理)
题意:求序列上某区间最小值乘区间长度的最大值. 解题关键:很早就在<挑战程序设计竞赛>中见过了,单调栈模板题,注意弹栈时如何处理后面的元素. 法一:单调栈 #include<bits ...
- Leetcode84. 柱状图中最大的矩形(单调栈)
84. 柱状图中最大的矩形 前置 单调栈 做法 连续区间组成的矩形,是看最短的那一块,求出每一块左边第一个小于其高度的位置,右边也同理,此块作为最短限制.需要两次单调栈 单调栈维护递增区间,每次不满足 ...
- hdoj - 1506 直方图中最大的矩形
Problem Description A histogram is a polygon composed of a sequence of rectangles aligned at a commo ...
随机推荐
- CentOS 7.9 安装 rocketmq-4.9.2
一.CentOS 7.9 安装 rocketmq-4.9.2 地址: https://rocketmq.apache.org https://github.com/apache/rocketmq ht ...
- k8s 中的 service 如何找到绑定的 Pod 以及如何实现 Pod 负载均衡
k8s 中的 service 如何找到绑定的 Pod 以及如何实现 Pod 负载均衡 前言 endpoint kube-proxy userspace 模式 iptables ipvs kernels ...
- Linux系统管理_网络管理
常用网络指令 yum -y install net-tools #安装ifconfig工具 ifconfig #查看网络配置 ifup ens33 #启用网卡 ifdown ens33 #禁用网卡 s ...
- Unexpected token u in JSON at position 0
文章目录 1.1 错误原因: 1.2 解决思路: 1.1 错误原因: 因为JSON.parse()不能解析字符串中的undefined 出错的结果:某一行的这个字段的值为空,就会报错,整个表格都显示不 ...
- 如何在IDEA中自定义模板、快速生成完整的代码?
文章目录 1.修改现有的模板 2.自定义模板 3.在代码中测试自定义模板 1.修改现有的模板 打开设置面板- settings 2.自定义模板 选择定义模板组 选择创建模板 define 代表应用的范 ...
- Go | 基本数据类型的相互转换
基本数据类型的相互转换 Go在不同类型的变量之间赋值时需要显示转换,不能自动转换 基本语法 表达式 T(v): 将值v转换成类型T T就是数据类型: int32, int64, float32... ...
- 中小型企业综合项目(Nginx+LVS+Tomcat+MGR+Nexus+NFS)
Nginx+Tomcat+Mysql综合实验 1.环境准备 服务器 IP地址 作用 系统版本 数据库服务器1 192.168.100.111 MGR集群数据库master节点 Rocky8.6 数据库 ...
- Python基础部分:4、 python语法之注释
目录 一.python语法之注释 1.什么是注释 2.如何编写注释 二.PEP8规范 一.python语法之注释 1.什么是注释 注释用来向用户提示或解释某些代码的作用和功能,它可以出现在代码中的任何 ...
- 论文笔记 - Noisy Channel Language Model Prompting for Few-Shot Text Classification
Direct && Noise Channel 进一步把语言模型推理的模式分为了: 直推模式(Direct): 噪声通道模式(Noise channel). 直观来看: Direct ...
- 「浙江理工大学ACM入队200题系列」问题 A: 零基础学C/C++34—— 3个数比较大小(冒泡排序与选择排序算法)
本题是浙江理工大学ACM入队200题第四套中的A题,同时给出了冒泡排序和选择排序算法 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习 ...
