본문 바로가기

알고리즘

[파이썬 | BOJ | 9084] 동전

https://www.acmicpc.net/problem/9084

 

9084번: 동전

우리나라 화폐단위, 특히 동전에는 1원, 5원, 10원, 50원, 100원, 500원이 있다. 이 동전들로는 정수의 금액을 만들 수 있으며 그 방법도 여러 가지가 있을 수 있다. 예를 들어, 30원을 만들기 위해서는 1원짜리 30개 또는 10원짜리 2개와 5원짜리 2개 등의 방법이 가능하다. 동전의 종류가 주어질 때에 주어진 금액을 만드는 모든 방법을 세는 프로그램을 작성하시오.

www.acmicpc.net

문제

우리나라 화폐단위, 특히 동전에는 1원, 5원, 10원, 50원, 100원, 500원이 있다. 이 동전들로는 정수의 금액을 만들 수 있으며 그 방법도 여러 가지가 있을 수 있다. 예를 들어, 30원을 만들기 위해서는 1원짜리 30개 또는 10원짜리 2개와 5원짜리 2개 등의 방법이 가능하다.

동전의 종류가 주어질 때에 주어진 금액을 만드는 모든 방법을 세는 프로그램을 작성하시오.

입력

입력의 첫 줄에는 테스트 케이스의 개수 T(1 ≤ T ≤ 10)가 주어진다. 각 테스트 케이스의 첫 번째 줄에는 동전의 가지 수 N(1 ≤ N ≤ 20)이 주어지고 두 번째 줄에는 N가지 동전의 각 금액이 오름차순으로 정렬되어 주어진다. 각 금액은 정수로서 1원부터 10000원까지 있을 수 있으며 공백으로 구분된다. 세 번째 줄에는 주어진 N가지 동전으로 만들어야 할 금액 M(1 ≤ M ≤ 10000)이 주어진다.

편의를 위해 방법의 수는 231 - 1 보다 작고, 같은 동전이 여러 번 주어지는 경우는 없다.

출력

각 테스트 케이스에 대해 입력으로 주어지는 N가지 동전으로 금액 M을 만드는 모든 방법의 수를 한 줄에 하나씩 출력한다.

 

풀이

동전이 작은 순으로 작은 동전으로만 사용해서 해당 M원을 구성하는 경우의 수를 더해가면 된다.

 

예를 들어 동전이 2, 3, 5원이 존재하고 1원부터 10원까지 경우의 수를 차례로 탐색한다고 생각해보자.

 

  1 2 3 4 5 6 7 8 9 10
2원 0 1 0 1 0 1 0 1 0 1
3원 0 1 0+1 1+0 0+1 1+1 0+1 1+1 0+2 1+1
5원 0 1 1 1 1+1 2+0 1+1 2+1 2+1 2+2

먼저 2원으로만 구성한다고 하면, 2원, 4원, 6원... 10원 까지 모두 1가지의 경우의 수가 생긴다.

 

3원까지 넣어서 구성한다고 하면, 3원은 1가지의 경우의 수가 생기므로, 기존 d[3]에다가 +1을 추가한다.

4원의 경우에는 3원을 넣는 경우의 수가 불가능하다. 이는 4-3, 1원의 경우 d[1] = 0이므로, 기존 d[4]에다가 +0을 추가하는 것으로 생각할 수 있다.

5원의 경우에는 5-3, 2원의 경우의 수가 1개가 있으므로 기존 d[5]에다가 d[2] = 1이므로, 기존 d[5]에다가 +1을 추가하면 된다.

 

이를 코드로 표현하면 다음과 같다.

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import sys
read = sys.stdin.readline
 
= int(read())
 
while T:
    N = int(read())
    coin = list(map(int, read().split()))
    M = int(read())
    d = [0 for _ in range(M+1)]
    d[0= 1
 
    for i in range(N):
        for j in range(coin[i], M+1):
            d[j] += d[j-coin[i]]
 
    print(d[M])
    T -= 1
cs