이번 문제는 주어진 동전들 중에서 최소의 개수 조합으로 K를 만드는 일종의 거스름돈 문제와 유사한 문제입니다.
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
---|---|---|---|---|---|
1 초 | 256 MB | 156277 | 84182 | 64205 | 52.855% |
준규가 가지고 있는 동전은 총 N종류이고, 각각의 동전을 매우 많이 가지고 있다.
동전을 적절히 사용해서 그 가치의 합을 K로 만들려고 한다. 이때 필요한 동전 개수의 최솟값을 구하는 프로그램을 작성하시오.
첫째 줄에 N과 K가 주어진다. (1 ≤ N ≤ 10, 1 ≤ K ≤ 100,000,000)
둘째 줄부터 N개의 줄에 동전의 가치 Ai가 오름차순으로 주어진다. (1 ≤ Ai ≤ 1,000,000, A1 = 1, i ≥ 2인 경우에 Ai는 Ai-1의 배수)
첫째 줄에 K원을 만드는데 필요한 동전 개수의 최솟값을 출력한다.
10 4200
1
5
10
50
100
500
1000
5000
10000
50000
6
10 4790
1
5
10
50
100
500
1000
5000
10000
50000
12
이 문제는 그리디 알고리즘을 사용하여 주어진 동전들로 가치의 합을 최소 개수로 만들어야 하는 문제입니다. 동전의 가치가 오름차순으로 주어지며, 각 동전의 가치는 그 이전 동전의 배수로 주어지기 때문에 큰 동전부터 사용하면 최적의 해를 구할 수 있습니다. 이 문제는 거스름돈 문제와 유사하며, 큰 금액의 동전부터 사용하여 최적의 해를 찾는 전형적인 그리디 알고리즘 문제입니다.
import sys
def solution(N, K, coin):
cnt = 0 # 동전 개수 카운터
# 동전 리스트를 뒤에서부터 (큰 값부터) 사용
for i in range(N - 1, -1, -1):
cnt += K // coin[i] # 해당 동전으로 몇 개 사용할 수 있는지 계산
K %= coin[i] # K에서 해당 동전으로 나눈 나머지를 계산
return cnt # 필요한 동전 개수 반환
# 입력 처리
N, K = map(int, sys.stdin.readline().split())
coin = []
for i in range(N):
coin.append(int(sys.stdin.readline().strip()))
# 결과 출력
print(solution(N, K, coin))
coin
리스트에서 가장 큰 동전부터 차례대로 K를 나누어 해당 동전을 몇 개 사용할 수 있는지 계산하고, 나머지 금액을 다음 작은 동전으로 처리합니다.range(N-1, -1, -1)
은 동전 리스트를 큰 값부터 순차적으로 처리하기 위한 반복문입니다. 동전 개수는 cnt
에 누적됩니다.K %= coin[i]
를 사용해 현재 동전으로 나누고 남은 금액을 처리합니다.N
에 비례하며, 주어진 동전의 리스트를 순회하면서 K를 처리합니다.이번 문제는 그리디 알고리즘의 대표적인 유형인 동전 문제로, 큰 금액의 동전부터 사용하여 최소한의 동전 개수로 K원을 만드는 문제였습니다. 이 문제의 핵심은 동전 리스트를 정렬하는 대신, 이미 오름차순으로 주어졌기 때문에 리스트를 뒤에서부터 순회하며 큰 동전부터 처리함으로써 불필요한 연산을 줄일 수 있었다는 점입니다.
따라서 정렬 작업 없이 동전 리스트를 뒤에서부터 순회하는 방식으로 시간 복잡도를 O(N)으로 유지하면서 문제를 해결할 수 있었습니다. 이는 동전 거스름돈 문제와 유사한 문제로, 그리디 알고리즘이 최적의 해를 보장하는 좋은 예시였습니다.
이번 문제를 통해 그리디 알고리즘의 원리를 다시 한 번 복습할 수 있었으며, 코딩 테스트에서도 자주 출제되는 유형이니 꼭 연습해두면 좋을 것입니다!
읽어주셔서 감사합니다!!
하루하루 발전하는 개발자가 될거야!