[3단계] 3. 거스름돈

이호용·2021년 4월 12일
0

프로그래머스

목록 보기
19/22

아래 모든 문제들은 프로그래머스에서 제공 되는 문제를 이용하였습니다, 감사합니다.

  • 틀린거 없음!

거스름돈

문제 설명

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 해주세요.

입출력 예

풀이

#include <string>
#include <vector>

using namespace std;

int solution(int n, vector<int> money) {
    vector <vector <int>> v(money.size(),vector <int>(n + 1,0));
    int answer = 0;
    int pos;
    for (int i = 0; i < money.size(); i++)
    {
        for (int j = 0; j <= n; j++)
        {
            pos = j - money[i];
            if(j == 0)
                v[i][j] = 1;
            else if(i == 0)
            {
                if(j % money[i] == 0)
                    v[i][j] = 1;
                else v[i][j] = 0;
            }
            else if(pos >= 0 && i != 0)
                v[i][j] = v[i-1][j] + v[i][pos];
            else v[i][j] = v[i - 1][j];
        }
    }
    return answer = v[money.size() - 1][n];
}

설명

  • 처음에는 bfs로 접근했는데, 나올수 있는 경우의 수가 너무 많아서 시간초과가 나왔다.
  • 고민끝에 점화식으로 접근해야한다는걸 깨닫고 이중배열을 만들어서 money의 작은 수부터 하나씩 늘려가며 나올수 있는 모든 조합을 이중배열에 저장해주었다.
  • 조합을 만들떄 하나씩 개수를 새지 않고 앞의 계산한 값들을 이용해주었다.
  • 아래 그림을 보면 이해하기 쉽다.

  • 이 문제의 포인트는 m(0)으로 만들수 있는 가지 수를 모두 정리해보고 그 값들을 이용해, m(1)을 만들수 있는 모든 조합을 다시 만들고 또 다음 값들을 m(1)을 이용해 순차적으로 만들어가면 효율성에 걸리지 않고 문제를 풀수 있다.

0개의 댓글

관련 채용 정보