[20250711] BOJ / D4 / 히스토그램 하나 빼기 / 권혁준 #436
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
🧷 문제 링크
https://www.acmicpc.net/problem/25611
🧭 풀이 시간
150분
👀 체감 난이도
✏️ 문제 설명
높이가 각각 H[i]인, N개의 막대로 이루어진 히스토그램이 있다.
S[i]를 i번째 막대를 제외하고 이어붙인 히스토그램에서의 최대 직사각형 넓이라고 할 때,
1 <= i <= N에 대해 S[i]를 모두 구해보자.
🔍 풀이 방법
여기서 막대를 제외시키는 작업이 없다면, 그냥 히스토그램 문제가 된다.
이 문제를 푸는 방법은
세그먼트 트리,스택,분할 정복등등 다양한 풀이가 존재하지만,분리 집합을 이용한 풀이도 존재한다.분리 집합으로 히스토그램 문제를 푸는 방법은 간략하게,
높은 막대부터 히스토그램에 차례로 추가시키며 좌우로 이미 추가된 막대들과 분리 집합으로 이어주는 것이다.
여기서 i번째 막대를 추가시킬 때, 양옆으로 이어진 막대들은 모두 i번째 막대보다 높이가 높거나 같다는 것을 이용한다.
그러면, i번째 막대를 뺐을 때 좌, 우에 있는 연결된 모든 막대들에 대해, (i번째 막대를 포함하는 최대 직사각형) - H[i]라는 값이 답의 후보가 될 수 있다.
또, i번째 막대와 연결되지 않은 다른 모든 막대들에 대해, (i번째 막대를 포함하는 최대 직사각형)이 답의 후보가 될 수 있다.
이처럼 여러 구간에 대해 max연산을 수행해서 정답을 갱신해야 하는데, 이를 깡으로 구현하면 시간 초과이기 때문에 max를 관리하는
세그먼트 트리를 사용한다.이 외에도 정답이 될 수 있는 경우의 수가 존재한다.
i번째 막대를 기준으로, 좌 우에 있는 막대 중 처음으로 H[i]보다 높이가 낮은 막대를 각각 L, R이라고 해보자.
그러면 L번째 막대가 사라졌을 때, L의 좌측으로 연결된 끝부터 i의 우측으로 연결된 끝까지가 모두 H[i] 높이를 수용할 수 있는 형태가 된다. 따라서, S[L]의 값도 갱신시킬 수 있다.
같은 논리로 R번째 막대가 사라졌을 때, R의 우측으로 연결된 끝지점부터 i의 왼쪽으로 연결된 끝까지가 모두 H[i]를 수용할 수 있다.
각 막대에 대한 L, R을 구할 때는 오큰수 문제처럼 스택으로 구할 수 있다.
이렇게 모든 조건을 다 고려해서 갱신을 마친 뒤 정답을 구해줬다.
⏳ 회고
자바로 다 짜놨는데 시간 초과가 떴다.
자바가 느려서 그렇겠거니 하고 C++로 다시 짜니까 맞음