限制大小的关键在于某一个矩形向左可以到什么地方,向右可以到什么地方。
如果可以得知这个长度,再乘以该矩形的高度就是我们所需要的该矩形的最大面积。
如果可以得知这个长度,再乘以该矩形的高度就是我们所需要的该矩形的最大面积。
然后枚举求出所有矩形的最大面积,求最大的那一个就可以了。
那么如何去向左和向右寻找最远的地方呢?我们可以将问题转换成找最近的阻挡点,那么就可以使用一个单调栈来维护这个最近的阻挡点。如果当前是最小的那一个,那么就不存在什么阻挡点所以直接将他的下标填到极限的地方,否则就去栈里面不断将大于等于该矩形高度的不断出栈,最后剩下的就是最近的阻挡点。右边的过程同样如此。
//限制大小的关键在于某一个矩形向左可以到什么地方,向右可以到什么地方。
//如果可以得知这个长度,再乘以该矩形的高度就是我们所需要的该矩形的最大面积。
//然后枚举求出所有矩形的最大面积,求最大的那一个就可以了。
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn = 100000+10;
ll a[maxn];
ll zuo[maxn];
ll you[maxn];
void find_zuo(int n) {
stack<ll> st;
for (int i=1;i<=n;i++) {
while (!st.empty()&&a[st.top()]>=a[i]) {
st.pop();
}
if (st.empty()) zuo[i] = 0;
else zuo[i] = st.top();
st.push(i);
}
}
void find_you(int n) {
stack<ll> st;
for (int i=n;i>=1;i--) {
while (!st.empty()&&a[st.top()]>=a[i]) {
st.pop();
}
if (st.empty()) you[i] = n+1;
else you[i] = st.top();
st.push(i);
}
}
void Merge(int n) {
for (int i=1;i<=n;i++) {
zuo[i] = you[i] - zuo[i] - 1;
}
}
int main() {
int n;
cin>>n;
while (n) {
for (int i=1;i<=n;i++) {
cin>>a[i];
}
find_zuo(n);
find_you(n);
Merge(n);
//求得结果
ll ans = 0;
for (int i=1;i<=n;i++) {
ans = max(ans, a[i]*zuo[i]);
}
cout<<ans<<endl;
cin>>n;
}
return 0;
}

京公网安备 11010502036488号