728x90

문제

 

 

접근 방식

맨 처음에 문제를 풀 때는 잘못 이해해서 정렬을 사용해서 풀 수도 있을 줄 알았는데

문제를 제대로 이해하고 보니 중간중간 계산 결과를 다시 넣을 때마다

정렬을 한다면 매우 비효율적이기 때문에 우선순위 큐를 사용해서 풀었다.

10 // 10개의 수가 주어졌을 때
123
456
234
998
12
7
876
887
455
234

 

만약 위와 같은 입력이 주어졌을 때 계산 순서는 다음과 같다.

7 + 12 = 19
19 + 123 = 142
142 + 234 = 376
376 + 234 = 610
610 + 455 = 1065
1065 + 456 = 1521
1521 + 876 = 2397
2397 + 887 = 3284
3284 + 998 = 4282

 

위 순서대로 계산하여 결과를 모두 더하면 13696이라는 답이 나오는데

이는 잘못된 풀이다.

7 + 12 = 19
19 + 123 = 142
142 + 234 = 376
234 + 376 = 610
455 + 456 = 911
610 + 876 = 1486
887 + 911 = 1798
998 + 1486 = 2484
1798 + 2484 = 4282

 

위와 같이 계산해서 결과를 모두 더했을 때 12108이라는 답이 나와야 정답이다.

 

처음 입력 받은 것을 정렬된 상태로 그대로 더하기만 해서 되는 문제가 아니라

두 카드 묶음을 더할 때마다 생기는 하나의 카드 묶음을 포함해서

다시 정렬된 상태로 계산해야 하기 때문이다.

 

이런 문제 때문에 처음 언급했던 것처럼 매번 정렬을 할 수도 없기 때문에

우선순위 큐를 사용해서 풀면 효율적인 것이다.

 

최소 힙의 규칙을 통해 항상 오름차순으로 우선순위 큐에서 값을 넣고 꺼낼 수 있기 때문에

두 카드 묶음을 합치고 합친 값을 다시 큐에 넣고 이를 반복하기만 하면

매번 정렬을 할 필요 없이 효율적으로 계산할 수 있다.

 

 

풀이

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 sum = 0;
		int min = 0;

		PriorityQueue<Integer> pq = new PriorityQueue<>();

		for (int i = 0; i < n; i++) pq.offer(Integer.parseInt(br.readLine()));

		while (!pq.isEmpty()) {
			if (sum == 0) sum = pq.poll();
			else {
				sum += pq.poll();
				pq.offer(sum);
				min += sum;
				sum = 0;
			}
		}

		System.out.println(min);
	}
}

 

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

[백준] 1781번 : 컵라면  (1) 2024.01.22
[백준] 1655번 : 가운데를 말해요  (1) 2024.01.22
[백준] 2075번 : N번째 큰 수  (0) 2024.01.22
[백준] 1927번 : 최소 힙  (0) 2024.01.22
[백준] 11286번 : 절댓값 힙  (1) 2024.01.21

+ Recent posts