题目给出一系列宽度为1,高度不定的矩形,希望求出这篇区域中的一个最大矩形的面积。
如果数据比较小,可以用最大子矩阵写,把没有矩形的地方方格值是0,有矩形的地方方格值是1。
然后求个最大子矩阵。但是题目n很大,矩形高度更大。则考虑模拟。
对于一个矩形,维护两个量,其左侧大于等于它高度的最远的一个矩形的位置记为l[i].
其右侧大于等于它高度的最远的一个矩形的位置记为r[i],则他是l[i]~r[i]这个区间内最低的一个矩形。
构成的面积是(r[i]-l[i]+1)*height[i]。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <algorithm>
using namespace std;
const int maxn = 100100;
typedef long long ll;
ll arr[maxn],l[maxn],r[maxn];
//l[i]放位置在i左侧,大于等于arr[i]且距i最远的位置。
//r[i]放位置在i右侧,大于等于arr[i]且距i最远的位置。
int main() {
int n;
while(~scanf("%d",&n)) {
if(n == 0) break;
ll ans = 0;
ll index;
stack<ll>st;
for(int i = 1; i <= n; i++) {
scanf("%lld",&arr[i]);
l[i] = 1;
r[i] = n;
}
for(int i = 1; i <= n; i++) {
index = (ll)i;
//找左侧第一个比arr[i]小的位置。index-1位置比第i个位置高。
while(index>1 && arr[i]<=arr[index-1]) {
index = l[index-1];
/*l[index-1]的地方是index-1左侧大于arr[index-1]距index-1最远的位置。
l[index-1]位置比arr[index-1]高,则l[index-1]的地方比arr[i]也高,再从
它开始往前翻找。*/
}
l[i] = index;
}
for(int i = n; i >= 1; i--) {
index = (ll)i;
while(index<n && arr[i]<=arr[index+1]) {
index = r[index+1];
}
r[i] = index;
}
for(int i = 1; i <= n; i++) {
ans = max(ans,(r[i]-l[i]+1)*arr[i]);
}
printf("%lld\n",ans);
}
return 0;
}