728x90

문제

 

접근 방식

세그먼트 트리를 사용해서 풀 수 있는 문제라는데 아직 배우지 않아서

세그먼트 트리에 대해서 간단하게 검색해 보니 재귀를 사용한 방식이라

스택으로도 풀 수 있는 문제라서 스택을 사용해서 풀어봤다.

 

눈으로는 이해가 쉽고 넓이가 바뀌는 구간을 찾아서 계산을 해주면

해결된다는 사실도 머리로는 쉽게 이해가 가능하지만

구현하려니 막상 머리가 안 돌아갔다...

 

우선, 간단하게만 생각해 보면

직사각형의 넓이는 다음 막대그래프의 높이가 낮아질수록

최대로 가능한 넓이가 작아질 것이고

다음 막대그래프의 높이가 같거나 높아야

최대로 가능한 넓이가 유지되거나 커진다.

 

정리하면 각각의 높이가 4 5 5인 막대그래프가 연속해서 존재하면

가능한 최대 높이는 가장 낮은 높이인 4와 연속된 그래프의 개수 3을 곱한

12가 나온다는 것을 알 수 있고

 

각각의 높이가 4 3 2인 그래프가 연속해서 존재하면

가능한 최대 높이는 가장 낮은 높이인 2와 연속된 그래프의 개수 3을 곱한

6이 나온다는 말이다.

 

즉, 스택에 구간이 바뀔 때까지 계속해서 쌓아주다가

구간이 바뀔 때 쌓아둔 그래프들은 비슷한 높이가 연속적으로 존재하기 때문에

모두 계산해 주면 그 구간의 최댓값을 구할 수 있다.

 

 

조심해야 할 부분은 위와 같이 이전까지의 모든 값들을 다 계산해줘야 한다는 것인데

지금의 경우에는 아래 표시한 영역의 넓이는 7이라 정답이 아니지만

만약 아래 표시한 영역의 넓이가 가장 큰 경우에 이 부분을 체크하지 않으면

잘못된 정답을 얻게 된다.

 

그래서 스택에서 값을 하나씩 꺼낼 때마다 각각 계산을 하여

현재까지 기록된 최댓값이랑 비교해서 저장해줘야 한다.

풀이

public class Main {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		int n = Integer.parseInt(br.readLine());

		int[] arr = new int[n + 2];
		for (int i = 1; i <= n; i++) arr[i] = Integer.parseInt(br.readLine());

		Stack<Integer> histograms = new Stack<>();
		histograms.push(0);

		int max = 0;

		for (int i = 1; i <= n + 1; i++) {
			while (!histograms.isEmpty()) {
				int prev = arr[histograms.peek()];
				if (prev <= arr[i]) break;
				histograms.pop();
				max = Math.max(max, prev * (i - histograms.peek() - 1));
			}
			histograms.push(i);
		}

		System.out.println(max);
	}
}

 

'Java > Algorithms' 카테고리의 다른 글

[백준] 1463번 : 1로 만들기  (0) 2023.12.11
[백준] 15683번 : 감시  (0) 2023.11.18
[백준] 7795번 : 먹을 것인가 먹힐 것인가  (1) 2023.11.16
[백준] 2910번 : 빈도 정렬  (1) 2023.11.16
[백준] 1181번 : 단어 정렬  (0) 2023.11.16

+ Recent posts