이번 문제는 1725번 히스토그램인데, 프알문의 울타리 잘라내기 문제와 풀이 방식이 똑같아 포스팅하였습니다.
울타리 잘라내기와 마찬가지로 이 문제를 브루트포스로 접근하게 되면 시간복잡도가 너무 높으므로 분할 정복으로 접근하였습니다.
지금부터 울타리를 반으로 쪼개며, 확장을 하면서 분할 정복을 할 것입니다. 먼저 기저사례를 기본적인 분할 정복에서의 기저사례와 같은 left==right일시 기본 높이 값을 반환해주며, 그 후 left~mid, mid+1~right로 나누어 계산을 할 것입니다.
먼저 반으로 쪼개가며 확장을 시키면 모든 케이스를 확인 할 수 있습니다. 그렇기 때문에 반으로 쪼개가는 것이고, 확장을 시킬 때 왼쪽으로 갈지 오른쪽으로 갈지는 더 높은 케이스를 찾아가도록 설정을 해주었습니다.
#include <iostream>
#include <math.h>
#include <vector>
#include <algorithm>
using namespace std;
int N;
vector<int> h;
int hisGram(int left, int right) {
if (left == right) {
return h[left];
}
int mid = (left + right) / 2;
int ret = max(hisGram(left, mid), hisGram(mid + 1, right));
//겹치는 경우
int lo = mid; int hi = mid + 1;
int height = min(h[lo], h[hi]);
ret = max(ret, height * 2);
//겹치고 나서 확장을 하자
while (left < lo || right > hi) {
if (hi < right && (left == lo || (h[lo - 1] < h[hi + 1]))){
++hi;
height = min(height, h[hi]);
}
else {
--lo;
height = min(height, h[lo]);
}
ret = max(ret, height*(hi - lo + 1));
}
return ret;
}
int main() {
cin >> N;
for (int i = 0; i < N; ++i) {
int tmp;
cin >> tmp;
h.push_back(tmp);
}
int ret = hisGram(0, h.size()-1);
cout << ret;
}
반응형
'Algorithm > Problem and Strategies' 카테고리의 다른 글
[백준] 11266번 - 단절점 (Articulation Point) (0) | 2020.04.29 |
---|---|
[백준] 10942번 - 팰린드롬? (2) | 2020.02.16 |
[백준] 1780번 종이의 개수 (0) | 2020.01.25 |
[백준] 1012번 유기농 배추 (0) | 2020.01.23 |
[백준] 2503번 숫자 야구 (0) | 2020.01.14 |