본문 바로가기

Algorithm

[프로그래머스] 코딩테스트 연습 - 거스름돈 (Python)

코딩테스트 연습 - 거스름돈 [2022 KAKAO BLIND RECRUITMENT]

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

쉽지 않은 문제였다고 생각됩니다.

제가 처음 접근했던 방법은 DFS였지만 효율성의 벽을 넘을 수는 없어서 다른 분들의 풀이를 참고하였습니다.

 

풀이

해당 문제를 풀이하면서 가장 중요한 키워드는 DP 입니다.

저처럼 DFS/BFS를 시도하신 분들이라면 선택된 동전의 순서로 인해 머리 아프시진 않으셨나요? (저는 그랬거든요ㅠ)

예를 들면 4원을 만들기 위해 (1,1,2) & (1,2,1) & (2,1,1) 은 모두 같은 동전의 개수를 사용하는 것이죠.

결국 포커스를 탐색 둔다면 아마 시간 초과로 인해 통과하기 힘들지 않을까 생각됩니다.

 

그래서 DP를 이용한 풀이는 다음과 같습니다.

(1) 하나의 동전 A 선택

(2) A 금액  ~ n원까지, A를 포함한 경우의 수 추가 

이때 memory [price] += memory [price-coin]에서 price - coin이 되는 이유는 예를 들어 설명해보겠습니다.

4원을 만들기 위해 (1,2)의 동전을 가지고 있고 하나의 1원을 포함하여 4원을 만들고 싶을 때 4(목표금액)-1(선택한 동전)=3(필요한 금액)을 만들어야 하고 필요한 금액 3을 만드는 경우는 (1,1,1), (1,2) 두 가지가 있겠죠.

이처럼 (1)에서 선택한 동전을 포함하는 경우를 찾기 위해 목표금액-선택한 동전=필요한 금액의 경우의 수를 찾아 더해주는 것입니다.

 

Code

def solution(n, money):
    memory = [0] *(n+1)
    memory[0] = 1 # baseline
    for coin in money:
        for price in range(coin, n+1):
            memory[price] += memory[price-coin]
    return memory[-1]%1000000007

 

문제 설명

Finn은 편의점에서 야간 아르바이트를 하고 있습니다. 야간에 손님이 너무 없어 심심한 Finn은 손님들께 거스름돈을 n 원을 줄 때 방법의 경우의 수를 구하기로 하였습니다.

예를 들어서 손님께 5원을 거슬러 줘야 하고 1원, 2원, 5원이 있다면 다음과 같이 4가지 방법으로 5원을 거슬러 줄 수 있습니다.

  • 1원을 5개 사용해서 거슬러 준다.
  • 1원을 3개 사용하고, 2원을 1개 사용해서 거슬러 준다.
  • 1원을 1개 사용하고, 2원을 2개 사용해서 거슬러 준다.
  • 5원을 1개 사용해서 거슬러 준다.

거슬러 줘야 하는 금액 n과 Finn이 현재 보유하고 있는 돈의 종류 money가 매개변수로 주어질 때, Finn이 n 원을 거슬러 줄 방법의 수를 return 하도록 solution 함수를 완성해 주세요.

 

제한 사항
  • n은 100,000 이하의 자연수입니다.
  • 화폐 단위는 100종류 이하입니다.
  • 모든 화폐는 무한하게 있다고 가정합니다.
  • 정답이 커질 수 있으니, 1,000,000,007로 나눈 나머지를 return 해주세요.
입출력 예
n money result
5 [1,2,5] 4