문제
105원을 50원, 10원, 5원, 1원 4개 동전으로 최소한의 동전으로 거스를수 있는 방법 구하기
해결 방법
재귀 호출을 사용할 때 와 비슷한 방법으로 다이내믹 프로그래밍을 사용할수 있다.
다른 점은 작은 액수부터 큰 액수의 방향으로 구해나간다는 점
CODE
function minCoins(coin, N, C) {
// # POINT1
// resultArray[i]에는 i원을 거슬러줄 때 필요한 최소 동전의 개수를 저장
// 마지막에 resultArr[C]를 반환합니다.
// 최솟값을 구하기 위해 resultArr의 모든 값을 매우 큰 값으로 초기화
var maxNum = Number.MAX_SAFE_INTEGER
var resultArr = Array(C + 1).fill(maxNum)
// C = 0일 때
resultArr[0] = 0
/*
* N: 동전 종류
* C: 거슬러줄 금액
*/
for(var i =1; i<=C; i++){
for(var j =0; j<N j++> ){
if(coin[j] < i){
var temp = resultArr[i-coin[j]];
if(temp != maxNum && temp + 1 < resultArr[i]){
resutArr[i] = temp + 1;
}
if( temp != maxNum && temp + 1 < resultArr[i]){
resultArr[i] = temp + 1;
}
}
}
}
for (var i = 1; i <= C; i++) {
for (var j = 0; j < N; j++) {
// # POINT2
// 현재 구하려는 금액보다 작은 액변가의 동전에 대해서만 검사
if (coin[j] <= i) {
var temp = resultArr[i - coin[j]]
// resultArr[0] = 0; 이기 때문에 가능.
// # POINT3
// i원의 최소 거스름돈 보다(resultArr[i])
if (temp != maxNum && temp + 1 < resultArr[i]) {
resultArr[i] = temp + 1
}
}
}
}
return resultArr[C]
}
var coin = [50, 10, 5, 1]
var N = coin.length
var C = 105
console.log(minCoins(coin, N, C))
call stack tree(상향식 접근방법)
예, i=5인 경우
* resultArr[i]: 거스름돈 i원의 최소 거스름돈 동전 개수
* temp: resultArr[i]를 구하기 위한 temporary 변수(동전 종류를 순회하면서 temp가 결정 됨)
- 50원, 10원은 coin[j] <= i에 부적합으로 5원, 1원만 가능
-
5원, 1원인 경우
- j=2, coin[j] = 5원
=> resultArr[5-5]
=> 0원 최소 거스름돈 동전 개수 0개(temp = 0)
=> resultArr[5] = 0(temp) + 1 = 1; - j=3, coin[j] = 1원
=> resultArr[5-1]
=> 4원 최소 거스름돈 동전 개수 4개(temp = 4)
=> resultArr[5] = 4(temp) + 1 = 5;
- j=2, coin[j] = 5원