HDU-1506 單調棧
阿新 • • 發佈:2019-01-03
直方圖是由在共同基線上排列的矩形序列組成的多邊形。矩形具有相等的寬度,但可以具有不同的高度。例如,左邊的圖顯示了由高度為2, 1, 4、5, 1, 3、3的矩形組成的直方圖,其中單位為矩形的寬度為1:
通常,直方圖用於表示離散分佈,例如文字中字元的頻率。請注意,矩形的順序,即它們的高度,是重要的。在直方圖中計算最大矩形的面積,該直方圖也是在公共基線上對齊的。右邊的圖形顯示了直方圖中最大的對齊矩形。
Input
多組測試資料 每組測試資料的第一行為n(1 <= n <= 100000), 表示圖形有n個小矩形構成. 接下來一行輸入n個整數h1, h2...hn (0 <= hi <= 1000000000, 1 <= i <= n), 表示每個小矩形的高度 n為0時程式結束
Output
僅輸出一行表示面積的最大值
Sample Input
7 2 1 4 5 1 3 3 4 1000 1000 1000 1000 0
Sample Output
8 4000
要求最大的矩形的面積.想一想可以得到最大面積就是從某一個矩形向兩邊擴充套件, 擴充套件的條件是左邊或者右邊的高度大於等於當前位置的高度. 這樣就可以得到最大的面積
單調棧實現
#include<iostream> #include<algorithm> #include<cstdio> #include<string.h> #include<string> #include<stack> using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; const int MAXN = 100000 + 100; ll a[MAXN]; int L[MAXN], R[MAXN]; int main(){ int n; while (scanf("%d", &n) != EOF && n){ stack<int> s; s.push(0); ll ans = 0; for (int i = 1; i <= n + 1; i++){ if (i <= n) scanf("%lld", &a[i]); else a[i] = 0; L[i] = R[i] = i; while (s.size() > 1 && a[s.top()] >= a[i]){//保證棧頂元素的下邊沒有大於自己的 //如果a[棧頂元素] >= a[當前元素], 那麼棧頂元素右邊的第一個小於自己的就是這個元素 R[s.top()] = i - 1; s.pop(); }//迴圈保證有一個左邊界 L[i] = s.top(); s.push(i); } for (int i = 1; i <= n; i++) ans = max(ans, (R[i] - L[i])*a[i]); printf("%lld\n", ans); } #ifdef __wh system("pause"); #endif return 0; } //6 2 5 2 5 5 2