이 문제는 동전의 종류가 주어질 때 주어진 금액을 만드는 모든 방법의 수를 구하는 문제이다.
특히 이 문제는 이전의 1, 2, 3 더하기 3 문제와 어떤 주어진 자연수를 특정 수의 합으로 나타내는 방법의 수를 구한다는 면에서 비슷하다. 다만, 이전 문제의 경우 같은 개수의 수를 사용하더라도 더하는 순서가 바뀌는 경우 다른 방법으로 취급했는데, 이 문제는 단순히 동전의 개수로만 방법의 수를 따지기에 순서를 고려하지 않는다는 점에서 약간의 차이가 있다.
그렇다면 이 문제는 어떻게 해결할 수 있을까? 이제는 동전의 개수로만 방법의 수를 따지기에, 각 동전에 대해 그 동전이 포함될 경우에 대해 방법의 수를 순차적으로 구해나간다. 예를 들어 동전이 1원짜리, 2원짜리 동전이 주어졌다고 할 때, 우선 1원짜리 동전으로만 1원부터 목표 금액까지 도달할 수 있는 경우의 수를 구한다. 물론 이 경우 모든 경우의 수가 1로 동일할 것이다. 그 다음 여기에 2원짜리 동전을 추가해 2원짜리 동전이 들어갈 경우 방법의 수를 2원부터 목표 금액까지 구한다. 이때 2원짜리 동전을 추가했을 때 j원을 만드는 방법의 수까지 구했다고 하자. 이때 j+2원을 만들기 위해서는 2원짜리 동전을 추가했을 때 j원을 만드는 각 방법에 2원을 추가하면 될 것이다. 그러므로 기존의 j+2원을 만드는 방법의 수에 j원을 만드는 방법의 수를 더하면 된다. 이때 기존에 j+2원을 만드는 방법은 1원짜리 동전으로만 만드는 방법이었다. 이를 j가 (목표 금액-2)원일 때까지 반복하면 2원짜리 동전을 추가했을 때 가능한 방법의 수를 구할 수 있다.
여기서 더하는 순서가 바뀌는 경우가 고려되지 않는 이유는 위 과정을 거칠 때 앞에서 나온 동전부터 차례대로 더하기 때문이다. 예를 들어 목표 금액이 10원일 때 1원짜리 동전을 4개, 2원짜리 동전을 3개 쓰는 경우 우선 1원짜리 동전만 사용하는 경우에 대해 목표 금액이 4원일 때 방법인 1+1+1+1을 구한 뒤, 2원짜리 동전을 사용하는 경우에서 이를 고려해 여기에 2원을 3번 넣어 1+1+1+1+2+2+2라는 방법을 도출해낸다. 여기서 2원을 1원보다 먼저 더하는 경우는 고려되지 않으므로, 항상 더하는 순서가 바뀌는 경우를 고려하지 않게 되는 것이다.
이를 코드로 구현하면 다음과 같다.
T = int(input())
for _ in range(T):
N = int(input())
coins = list(map(int, input().split()))
m = int(input())
# 주어진 동전으로 각 금액을 만드는 모든 방법의 수를 저장하는 배열
dp = [0 for _ in range(m+1)]
# 초기값 설정
dp[0] = 1
for coin in coins:
for j in range(m+1-coin):
dp[j+coin] += dp[j]
print(dp[m])
'알고리즘 문제' 카테고리의 다른 글
백준 11403번 : 경로 찾기 in Python (0) | 2021.06.22 |
---|---|
백준 4963번 : 섬의 개수 in Python (0) | 2021.06.22 |
백준 5582번 : 공통 부분 문자열 in Python (0) | 2021.06.19 |
백준 2302번 : 극장 좌석 in Python (0) | 2021.06.19 |
백준 11060번 : 점프 점프 in Python (0) | 2021.06.19 |