프로그래머스 Lv.3 - 거스름돈 (DP) Python 본문
https://school.programmers.co.kr/learn/courses/30/lessons/12907
해당 문제는 각 돈의 종류로 특정 값을 만들 수 있는 모든 경우의 수를 출력하는 문제다.
이 또한 지난 포스팅과 같이 다이나믹 프로그래밍으로 풀이가 가능하다.
즉 위 문제 예시와 같이, n = 5원 / money = [1,2,5]라면
리스트 money에 있는 동전으로 만들 수 있는 0원 ~ 5원까지의 경우의 수를 구해나가며 5원을 만들 수 있는 경우의 수를 구할 수 있다.
먼저 경우의 수를 담을 리스트를 선언한다.
이때, 앞서 언급한 것과 같이 0원 ~ 5원을 만들 수 있는 경우의 수를 담아야 하므로 리스트의 길이는 n+1 이고 초깃값은 0이다.
하지만, 0원을 만드는 경우는 '모든 돈을 사용하지 않는 경우' 뿐이므로, dp[0]은 1 로 수정한다.
dp = [0] * (n+1)
dp[0] = 1
그리고 이 문제를 어떤 식으로 해결하면 좋을지 표를 먼저 그린 뒤 쪼개어 생각해본다.
인덱스 | 0원 | 1원 | 2원 | 3원 | 4원 | 5원 |
1원 | X | (1) | (1,1) | (1,1,1) | (1,1,1,1) | (1,1,1,1,1) |
1원 + 2원 | X | X | (2) | (2,1) | (2,2), (2,1,1) | (2,2,1), (2,1,1,1) |
1원 + 2원 + 5원 | X | X | X | X | X | (5) |
경우의 수 | 1 | 1 | 2 | 2 | 3 | 4 |
1원과 2원으로 1원을 만드는 방식은 1원을 하나 사용하는 한가지가 존재한다. (1)
1원과 2원으로 2원을 만드는 방식은 1원을 두 개 사용하는 방식과, 2원을 하나 사용하는 방식이 존재한다. (1,1), (2)
이때 2원을 만들기 위해, 1원을 만드는 방식인 (1)에서 1원을 또 추가한 방식인 (1,1)로 2를 만들 수 있고,
최소 2원을 만들기 위해서, 2원을 사용할 수 있으므로 (2)를 만들 수 있다는 사실을 알 수 있다.
그리고 더 나아가 3원을 만들 때는 2원을 만드는 방식에서 1원을 추가하여 (1,1,1),
1원을 만드는 방식에서 2원을 추가하여 (1,2)을 만들 수 있다.
즉 3원을 만드는 경우의 수는
(3-'1')원을 만드는 경우인 (1,1)에 '1'원을 더하는 경우와,
(3-'2')원을 만드는 경우인 (1)에 '2'원을 더하는 경우의 합이다.
즉, n이 m을 포함한 경우의 수를 구하기 위해서는 n - m 을 만드는 경우에서 참조해야 한다.
이를 활용하여 전체 코드를 작성하면 다음과 같다.
def solution(n, money):
money.sort()
dp = [0] * (n+1)
dp[0] = 1
for coin in money :
for i in range(coin, n+1) :
dp[i] += dp[i-coin]
return dp[n]
'개발 > algorithm' 카테고리의 다른 글
백준15815 - 천재 수학자 성필 (스택) Python (0) | 2023.11.11 |
---|---|
백준2713 - 규현이의 사랑을 담은 문자메시지 Python (0) | 2023.11.10 |
백준11053 - 가장 긴 증가하는 부분 수열 (DP) Python (0) | 2023.11.08 |
백준1991 - 트리순회 (그래프, 재귀) Python (0) | 2023.11.07 |
백준1283 - 단축키 지정 JS (0) | 2023.11.06 |