poj 2059 單調棧
阿新 • • 發佈:2017-08-19
1.0 sca eas down rec cpp 操作 string typedef
- 題意:求柱狀圖中最大矩形面積。
- 單調棧:顧名思義就是棧內元素單調遞增的棧。
每次插入數據來維護這個棧,假設當前須要插入的數據小於棧頂的元素,那就一直彈出棧頂的元素。直到滿足當前須要插入的元素大於棧頂元素為止。能夠easy求出某個數左邊或右邊,第一個大於或小於它的數,且復雜度是
O(n) 。 - 思路:easy先想到一個好的枚舉方式:以當前柱狀為擴展點,往左邊和右邊擴展。當遇到一個比當前柱狀小的柱狀時停止擴展。以當前柱狀的高度為矩形的高。向左右擴展的距離之差為矩形的長度,這樣對
n 個柱狀進行掃描之後可得最大矩形,復雜度是O(n2) ,顯然超時。本題用單調棧來做,維護一個條形圖高度的單調棧。
- 心得:一定要想好了思路,並用偽代碼在草稿紙上寫一遍再動手寫,這道題單調棧實現部分花了大量時間debug,源於思路不清晰。
簡潔的實現:
1.讀入當前柱狀的高度h。若h大於棧頂元素,則向棧中push(h, i) (i為當前柱狀的編號)。若h小於棧頂元素,則彈出棧頂元素,並得到
(i?topi)?toph 為棧頂柱狀所能擴展得到的最大矩形面積,以此面積來更新全局的最大面積。反復上操作,指導棧頂元素小於當前元素。
2.最後得到一個單調遞增的棧,再來用(n?topi)?toph 來表示棧頂元素所能組成的最大面積。處理並更新完整個棧就可以。註:我的代碼實現,沒實用事實上點做標記,而是一直條形圖合並的方法,代碼實現復雜了一些
我的代碼:
#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long int LL;
const int M = 100009,INF = 0x3fffffff;
int main(void) {
//problem: poj2559, address:http://poj.org/problem?id=2559
LL n, ans = -1, temp;
while (scanf("%lld",&n), n) {
ans = -1;
pair<LL, LL> key(-99999999 , 1);
stack<pair<LL, LL> > s;
s.push(key);
for (int i = 1; i <= n; i++) {
key.second = 1;
scanf("%lld", &key.first);
int k = 0 ;
while (s.top().first >= key.first) {
temp = LL(s.top().second + k)*LL( s.top().first);
if (temp > ans) ans = temp;
key.second += s.top().second;
k += s.top().second;
s.pop();
}
s.push(key);
}
for (int i = 0; !s.empty();) {
temp = LL(s.top().first) * LL(i + s.top().second);
if(temp > ans) ans = temp;
i += s.top().second;
s.pop();
}
printf("%lld\n", ans);
}
return 0;
}
poj 2059 單調棧