💻 Problem
정렬된 두 묶음의 숫자 카드가 있다고 하자. 각 묶음의 카드의 수를 A, B라 하면 보통 두 묶음을 합쳐서 하나로 만드는 데에는 A+B 번의 비교를 해야 한다. 이를테면, 20장의 숫자 카드 묶음과 30장의 숫자 카드 묶음을 합치려면 50번의 비교가 필요하다.
매우 많은 숫자 카드 묶음이 책상 위에 놓여 있다. 이들을 두 묶음씩 골라 서로 합쳐나간다면, 고르는 순서에 따라서 비교 횟수가 매우 달라진다. 예를 들어 10장, 20장, 40장의 묶음이 있다면 10장과 20장을 합친 뒤, 합친 30장 묶음과 40장을 합친다면 (10 + 20) + (30 + 40) = 100번의 비교가 필요하다. 그러나 10장과 40장을 합친 뒤, 합친 50장 묶음과 20장을 합친다면 (10 + 40) + (50 + 20) = 120번의 비교가 필요하므로 덜 효율적인 방법이다.
N개의 숫자 카드 묶음의 각각의 크기가 주어질 때, 최소한 몇 번의 비교가 필요한지를 구하는 프로그램을 작성하시오.
- 1 ≤ N ≤ 100,000
💡 Approach
처음에는 리스트를 정렬해서 맨 앞 두 개의 값을 더해 가는 방식으로 풀었다.
틀린 코드는 맞지만.. 틀렸습니다가 아니라 메모리 초과가 떠서 의아했다.
메모리 제한이 128 MB인데 이는 2^7 * 10^6이다.
int가 4 byte니까 2^5 * 10^6까지 가능하다.
N은 10^5니까 가능한데...
그래서 힙으로 풀어봤다.
이 과정에서 처음에 푼 방법이 틀렸다는 걸 알게 됐다.
맨 처음에 한 번만 정렬하고 누적해서 더하면 된다고 생각했는데, 두 카드 묶음을 더할 때마다 이를 재정렬해줘야 했다.
그래서 힙 구조가 필요한 것이다.
✏️ Solution
import sys
import heapq
input = sys.stdin.readline
N = int(input())
cards = []
cnt = 0
for _ in range(N):
heapq.heappush(cards, int(input()))
while len(cards) > 1:
a = heapq.heappop(cards)
b = heapq.heappop(cards)
cnt += a + b
heapq.heappush(cards, a + b)
print(cnt)
'Algorithm > 백준 (BOJ)' 카테고리의 다른 글
[Python] 백준/BOJ 2784번: 가로 세로 퍼즐 (Silver 2) (0) | 2025.08.02 |
---|---|
[Python] 백준/BOJ 1270번: 전쟁 - 땅따먹기 (Silver 3) (0) | 2025.07.28 |
[Python] 백준/BOJ 1515번: 수 이어 쓰기 (Silver 3) (0) | 2025.07.19 |
[Python] 백준/BOJ 31395번: 정렬된 연속한 부분수열의 개수 (Silver 4) (0) | 2025.07.17 |