題目地址:HISTOGRA - Largest Rectangle in a Histogram - 洛谷
經典找最大子矩陣問題。
對於一個陡峭不平的直方圖,每一個柱子都有不同的高度,透過觀察可以知道,如果兩根柱子組成的最大子矩陣他的高度必然不會超過較矮的矩陣高度。
有了這個思維,就可以知道一旦遇到比當前柱子要矮的柱子,就要立馬進行結算,但是這裡有一個問題,就是如果前面的柱子也是陡峭不平的,那麼就算結算,顯然答案也是不對的。
所以我們會想到利用單調棧,讓棧內元素保持升序,如果遇到比棧頂要小的元素就結算,並且每次彈棧就把當前棧頂元素的高,作為子矩陣的高,把比他高的矩陣的寬加上自己的寬,作為子矩陣的寬。紀錄寬度和高度顯然用結構體比較方便。
實現原理也非常簡單,只需要保證棧內元素是升序的,並且一旦遇到較棧頂元素小的柱子就要結算。
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
struct node{
long long val, len = 1;
}a[100000];
long long maxx = -1;
vector<node> s;
int x;
int main(){
int n;
while(cin >> n){
memset(a, 0, sizeof(a));
for(int i = 1; i <= n; i++){
cin >> a[i].val;
}
s.push_back(a[1]);
for(int i = 1; i <= n; i++){
int w = 0;
while(!s.empty() && s.back().val >= a[i].val){
w+=s.back().len;
maxx = max(maxx, w*s.back().val);
s.pop_back();
}
a[i].len = w + 1;
s.push_back(a[i]);
}
int w = 0;
while(!s.empty()){
w+=s.back().len;
maxx = max(maxx, w*s.back().val);
s.pop_back();
}
cout << maxx << endl;
}
}