9715 相邻最大矩形面积
Description
在X轴上水平放置着
N
N
N个条形图,这
N
N
N个条形图就组成了一个柱状图,每个条形图都是一个矩形,每个
矩形都有相同的宽度,均为
1
1
1单位长度,但是它们的高度并不相同。
例如下图,图1包含的矩形的高分别为
2
,
1
,
4
,
5
,
1
,
3
,
3
2,1,4,5,1,3,3
2,1,4,5,1,3,3单位长度,矩形的宽为
1
1
1单位长度。
你的任务就是计算柱状图中以 X X X轴为底边的最大矩形的面积。图2阴影部分就是上述例子的最大矩形面积。
输入格式
输入数据的第一行是一个整数 N(1≤ N ≤100000),表示柱状图包含 N 个矩形。
紧接着 N 个整数h1,…,hn(0≤ hi ≤20000, 1≤ i≤ N),表示柱状图中按从左到右顺序给出的矩形
的高度。矩形的宽度为1。
输出格式
输出一个整数S,表示以X轴为底边的最大矩形的面积。
输入样例
7
2 1 4 5 1 3 3
输出样例
8
思路:
- 首先题目给出提示为O(n 2)复杂度算法,计算最大矩形面积,考虑遍历每个单位矩形,双指针左右查看其延申的边界,然后取其中最大面积为答案。复杂度为O(n 2);
- 但数据N范围为1e5,有超时风险,考虑优化。观察到:其左右延申的距离最多至第一个小于其高的矩形处。问题转化为:求每个单位矩形,其左右第一个小于其高的矩形位置。答案为其延申宽度 乘以该单位矩形的高,再取最大值即可。
- 单调栈可以很好地解决该问题并把时间复杂度降低到O(n);
代码思路:
左右分两次跑一遍单调栈,其延申截止位置存储在l,r数组中(注意初始化),最后计算取max即可
tip:不了解单调栈的可以先去学习下其实现思路
//power by lxh #&10084
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#define int long long
using namespace std;
const int N = 2e6 + 7;
const int INF = 0x3f3f3f3f;
int n, m;
int s[N];
int r[N];
int l[N];
signed main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> s[i]; r[i] = n; l[i] = 1;
}
stack<int>st;
for (int i = 1; i <=n; i++)
{
int now = s[i];
while (st.size() && now < s[st.top()])
{
int hh = st.top();
r[hh] = i - 1;//向右延申到此为止
st.pop();
}
st.push(i);
}
stack<int>st1;
for (int i = n; i > 0; i--)
{
int now = s[i];
while (st1.size() && now < s[st1.top()])
{
int hh = st1.top();
l[hh] = i + 1;//向左延申到此为止
st1.pop();
}
st1.push(i);
}
int ans = 0;
for (int i = 1; i <= n; i++)
ans = max(ans, s[i] * (r[i] - l[i]+1));
cout << ans << endl;
}