时间限制: 1秒
空间限制: 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。
//
// 直方图最大面积.cpp
// 预习
//
// Created by 廖启帆 on 2019/11/14.
//
#include <iostream>
using namespace std;
// n:意义如题
// height:高度数组,height[i]表示第i列的高度(下标从1开始),数组大小为n+2,其中height[0]和height[n+1]都为0
// 返回值:题目所求答案,即最大面积
int dpleft[50010]={0},dpright[50010]={0};
long long getAnswer(int n, int *height) {
height[0]=-1;
height[n+1]=-1;
for (int i=1; i<=n; i++) {
int j=i;
dpleft[1]=1;
while (height[j-1]>=height[i]) {
j=dpleft[j-1];
}
dpleft[i]=j;
}
for (int i=n; i>=1; i--) {
int j=i;
dpright[n]=n;
while (height[j+1]>=height[i]) {
j=dpright[j+1];
}
dpright[i]=j;
}
long long max=0;
for (int i=1; i<=n; i++) {
if ((dpright[i]-dpleft[i]+1)*height[i]>max) {
max=(dpright[i]-dpleft[i]+1)*height[i];
}
}
return max;
}
int main()
{
int n;
cin >> n;
int* height = new int[n + 2]();
for (int i = 1; i <= n; ++i) {
cin >> height[i];
}
cout << getAnswer(n, height) << endl;
delete[] height;
return 0;
}
1.注意使用long long保存每次计算面积
2.直方图中会有0的情况出现,把height[0]、height[n+1]初始化为-1作为边界。
时间复杂度:O(N)