문제 : 동전교환
문제 설명
다음과 같이 여러 단위의 동전들이 주어져 있을 때 거스름돈을 가장 적은 수의 동전으로 교환해주려면 어떻게 주면 되는가? 각 단위의 동전은 무한정 쓸 수 있다.
▣ 입력설명
첫 번째 줄에는 동전의 종류 개수 N(1<=N<=12)이 주어진다. 두 번째 줄에는 N개의 동전의 종류가 주어지고, 그 다음줄에 거슬러 줄 금액 M(1<=M<=500)이 주어진다. 각 동전의 종류는 100원을 넘지 않는다.
▣ 출력설명
첫 번째 줄에 거슬러 줄 동전의 최소 개수를 출력한다.
▣ 입력예제 1
3
1 2 5
15
▣ 출력예제 1
3
설명 : 5 5 5 동전 3개로 거슬러 줄 수 있다.
내코드
function solution(m, arr) {
let sortArr = arr.sort((a, b) => b - a); // 동전을 내림차순으로 정리
// 주어진 거스름돈을 가장 큰 동전으로 나눈 몫을 올림한 값으로 거스름돈에 사용될 가능한 최소 개수를 의미
const MIN_POSSIE_COUNT = Math.ceil(m / arr[0]);
let answer = Number.MIN_SAFE_INTEGER;
let answerArr = []; // 로직과 별개로 정답을 구하는데 사용된 동전조합을 의미할 배열
// 남은 거스름돈을 의미할 인자 num, 계산한 사용한 동전 개수를 의미할 인자 count, 현재까지 사용된 동전 조합을 의미할 배열 인자 checkArr
// 위 인자들로 남은 거스름돈을 재귀적으로 계산할 DFS 함수 선언
function DFS(num, count = 0, checkArr = []) {
// 이미 가능한 최소 값에 도달했다면 이후 함수과정을 스킵
if (answer === MAX_POSSIE_COUNT) return;
// 거스름돈이 0 일 때 현재까지 사용한 동전 개수를 현재까지 최소값과 비교 후 더 작은 경우 저장
if (num === 0) {
answer = Math.min(answer, count);
answerArr = checkArr;
return;
}
// 거스름돈이 0 보다작아진 즉 제대로 거스름돈을 줄 수 없는 경우이거나
// 이미 거스름돈에 사용한 동전이 최소값과 같거나 크다면 남은 거스름돈 계산이 의미없으므로 함수 종료
if (num < 0 || count >= answer) return;
// 아직 거스름돈이 남은 경우 높은 동전 부터 계산한 거스름돈을 인자로 DFS 함수에 재귀적으로 호출
else {
for (let i = 0; i < sortArr.length; i++)
DFS(num - sortArr[i], count + 1, [...checkArr, sortArr[i]]);
}
}
DFS(m);
console.log("거스름돈에 사용한 동전 조합: ", answerArr);
return answer;
}
let arr = [1, 2, 5];
console.log(solution(15, arr));
풀이
- 주어진 여러 단위의 동전들 (
arr
배열) 을 내림차순으로 정렬, 주어진 거스름돈을 가장 큰 동전(arr[0]
) 으로 나눈 몫을 올림한 값으로 거스름돈에 사용될 가능한 최소 동전 개수를 의미 - 남은 거스름돈을 의미할 인자
num
, 계산한 사용한 동전 개수를 의미할 인자count
위 인자들로 남은 거스름돈을 재귀적으로 계산할DFS
함수 선언 - 거스름돈을 높은 동전부터 계산한 거스름돈을 인자로
DFS
함수를 재귀적으로 호출 - 계산해 가면서 거스름돈이 0 일 때 모든 거스름 계산 과정이 마무리된 것으로 현재까지 사용한 동전 개수를 현재까지 최소 값(
answer
)과 비교 후 더 작은 경우 정답 변수(answer
) 에 저장 - 거스름돈 계산 과정에서 거스름돈이 0 보다 작아진 즉 제대로 거스름돈을 줄 수 없는 경우이거나, 이미 거스름돈에 사용한 동전이 최소 값과 같거나 크다면 남은 거스름돈 계산이 의미 없으므로 함수 종료해 이후 거스름 계산 과정을 스킵
- 현재까지 최소 값(
answer
)이 이미 가능한 최소 값(MIN_POSSIE_COUNT
)에 도달했다면 더 이상 최소 값을 구할 필요가 없으므로 return 하여 이후 모든 재귀 함수 과정을 스킵
참고
'코딩 테스트 문제 및 풀이' 카테고리의 다른 글
[JS] 코딩 테스트 문제 : 수열 추측하기 [순열, 이항계수, 파스칼 삼각형] (0) | 2024.02.28 |
---|---|
[JS] 코딩 테스트 문제 : 조합의 경우수(메모이제이션) [스택] (0) | 2024.02.01 |
[JS] 코딩 테스트 문제 : 중복순열 구하기 [재귀함수] (0) | 2024.01.29 |
[JS] 코딩 테스트 문제 : 바둑이 승차 [DFS] (0) | 2024.01.28 |
[JS] 코딩 테스트 문제 : 합이 같은 부분집합 [DFS] (0) | 2024.01.24 |