#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;
int n;
int height[100002];
stack<int> highestIndexStack;
int main() {
while (true) {
scanf("%d", &n);
if (n == 0) return 0;
for (int i = 0; i < n + 2; i++) height[i] = 0;
for (int i = 1; i <= n; i++) scanf("%d", &height[i]);
long long result = 0;
int now = 0;
highestIndexStack.push(0);
for (int i = 1; i <= n + 1; i++) {
while (true) {
if (highestIndexStack.size() == 0) break;
int prevIndex = highestIndexStack.top();
if (height[prevIndex] < height[i]) {
break;
}
highestIndexStack.pop();
if (highestIndexStack.size() > 0) {
long long nowArea = (long long)height[prevIndex] * (long long)(now - highestIndexStack.top());
if (nowArea > result) result = nowArea;
}
}
highestIndexStack.push(i);
now++;
}
cout << result << endl;
}
return 0;
}
예전에 책에서 봤다가, O(n^2) 일거 같은게 O(n)으로 풀리는게 당시에 엄청 문화충격이여서 몇번 풀었었다.
덕분에 기억이 나서 풀 수 있었던 문제.
i = 1..N 에 대하여,
height[i]가 스택의 top()에 있는 인덱스의 높이보다 낮을 경우, 그 값들을 빼면서 넓이 계산.
이걸 height[스택.top()] 보다 height[i]가 더 높을때까지 빼면서 계산
그 후 스택에 i를 넣는다
스택에는 높이가 아니라 index를 저장했고,
스택의 첫 부분에 0을 넣고, 맨 뒤에도 0을 넣음으로써 마지막에 스택에서 왕창 빼면서 넓이를 계산할 수 있게 하였다.
너무나 유명한 문제니까 이만 말을 줄이겠다... ㅋㅋㅋㅋ
'코딩 > 알고리즘' 카테고리의 다른 글
백준 1992 쿼드트리 (0) | 2017.06.05 |
---|---|
백준 2740 행렬 곱셈 (0) | 2017.06.05 |
백준 1780 종이의 개수 (0) | 2017.06.04 |
백준 11004 K번째 수 (0) | 2017.06.02 |
[C#] 백준 2749 피보나치수 3 (0) | 2017.05.28 |