-
[프로그래머스] 거스름돈 Java 풀이문제풀이/프로그래머스 2021. 11. 25. 14:16반응형
이 글은 혼자 학습한 내용을 바탕으로 작성되었습니다.
틀리거나 잘못된 정보가 있을 수 있습니다.
댓글로 알려주시면 수정하도록 하겠습니다.
1. 문제
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 함수를 완성해 주세요.
2. 입력
- n은 100,000 이하의 자연수입니다.
- 화폐 단위는 100종류 이하입니다.
- 모든 화폐는 무한하게 있다고 가정합니다.
- 정답이 커질 수 있으니, 1,000,000,007로 나눈 나머지를 return 해주세요.
3. 예제
n money result 5 [1,2,5] 4 4. 풀이
문제를 풀기 위해 만든 DP 2차원 배열에는 X축은 N까지의 금액이 되며 Y축에는 동전들의 그룹이 나열됩니다.
예제를 DP표로 만들게 되면 위 표와 같이 됩니다.
위 표의 가장 윗줄(빨간색 행)은 해당 행의 동전으로 거스름돈 금액을 거슬러 줄 수 있으면 1을 없으면 0을 입력합니다.
즉 해당 동전으로 나누어 떨어지면 1을 나누어 떨어지지 않으면 0을 입력합니다.
이유는 해당 동전으로 금액을 만들어지는 경우는 나누어서 떨어지는 경우 1건만 존재하기 때문입니다.
- 1원을 거슬러 주는 경우는 1원 동전 1개를 거슬러 준 경우 1건입니다.
- 2원을 거슬러 주는 경우는 1원 동전 2개를 거슬러 준 경우 1건입니다.
첫 줄을 위 과정으로 채워 넣은 결과표는 위와 같습니다.
※모든 금액은 1원 동전으로 모두 거슬러 줄 수 있으므로 모두 1이 됩니다.
위 표의 두번째 줄(파란색 행)은 해당 행은 해당 동전보다 금액이 적은 경우와 큰 경우 2가지로 나누어집니다.
- 동전보다 금액이 적은 경우
동전보다 금액이 적은 경우는 해당 동전으로 거슬러 줄 수 없는 경우 이므로 이전 동전으로 거슬러 줄 수 있는 경우의 수를 그대로 가지고 옵니다.
즉 1원의 경우 2원 동전으로 거슬러 줄 수 없으므로 1원 동전으로 거슬러준 경우의 수 1을 그래도 작성합니다. - 동전보다 금액이 큰 경우
동전보다 금액이 큰 경우는 거슬러 주어야 하는 금액의 바로 직전의 동전 경우의 수에 거스름돈 금액에 동전 금액 만큼 뺀 값의 경우수를 더해주면 됩니다.
즉 3원을 2원 동전으로 거슬러 주는 경우는 1원으로 3원을 만드는 경우의 수 1 + 2원으로 1원을 만드는 경우의 수 1을 더한 2가 정답이 됩니다.
동전보다 금액이 큰 경우를 추가로 설명 하자면 {1, 2} 동전 그룹으로 3원을 만드는 경우의 수는 2가지 입니다.
3원에서 가장 뒤에 2원을 추가 하면 5원을 만드는 경우의 수가 됩니다.
이제 위 2가지 경우에 1원 동전으로 5원을 만드는 경우 1가지를 더하면 총 3가지 경우로 {1, 2} 동전 그룹으로 5원을 만들 수 있습니다.
두번째 줄을 위 과정으로 채워 넣은 결과표는 위와 같습니다.
세번째 줄을 위 과정으로 채워 넣은 결과표는 위와 같습니다.
정답은 DP 2차원 배열의 최하단의 오른쪽 값이 결과 값이 됩니다.
5. 코드
전체 코드는 Git에 있습니다.
int[][] dp = new int[money.length][n + 1]; for(int i=0; i< money.length; i++) dp[i][0] = 1; for(int i=1; i<=n; i++) dp[0][i] = i % money[0] == 0 ? 1 : 0; for(int i=1; i<money.length; i++){ for(int j=1; j<=n; j++){ if(money[i] <= j) dp[i][j] = dp[i-1][j] + dp[i][j - money[i]]; else dp[i][j] = dp[i-1][j]; } } return dp[money.length-1][n];
반응형'문제풀이 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 스티커모으기(2) Java풀이 (2) 2021.12.07 [프로그래머스] 모음사전 Java 풀이 (0) 2021.12.03 [프로그래머스] 멀리 뛰기 Java 풀이 (0) 2021.11.23 [프로그래머스] 야근 지수 Java 풀이 (0) 2021.11.22 [프로그래머스] 등굣길 Java 풀이 (0) 2021.11.22