时间限制:1 sec
空间限制:256 MB
问题描述
有一个直方图,横轴长度为 n,第 i 列的高度为 h[i]。
请你求出在这个直方图中面积最大的子矩阵。
输入格式
第一行一个正整数 n。
第二行 n 个用空格隔开的非负整数,依次描述 h[1],h[2],…,h[n]。
输出格式
输出一行一个数,表示最大面积。
样例输入
5
2 3 3 3 2
样例输出
10
数据范围
对于 30% 的测试点,保证 n<=4。
对于 70% 的测试点,保证 n<=1000。
对于所有测试点,保证 n<=50000。
保证所有 h[i] 不超过 32767。
思路:利用栈,当高度H单调增时入栈,遇到下降情况重复将栈顶元素弹出,直至碰见<=m[k]的元素为止,过程中对应的每一个H即为矩形高。(注意在最后放置哨兵)
C++实现:
#include<stdio.h>
#include<stack>
#define maxn 50050
using namespace std;
int calculate(int m[],int n);
int main(){
int n,ans;
int m[maxn];
scanf("%d",&n);
for(int i = 0;i<n;i++){
scanf("%d",&m[i]);
}
m[n]=-1;
ans =calculate(m,n);
printf("%d",ans);
return 0;
}
int calculate(int m[],int n){
int maxrect = 0, rect = 0, k=0;
stack<int> s;
while(k <= n){
if(s.empty() || m[k] >= m[s.top()]){s.push(k); k++;}
else {
int h = s.top();
s.pop();
if(s.empty()) rect = k * m[h];
else rect = m[h] * (k - s.top() - 1);//注意此处为什么是s.top()而不是h
maxrect = max(rect,maxrect);
}
}
return maxrect;
}