이번엔 거스름 돈을 줄때 동전 갯수가 최소가 되게 하면 된다. changes = 15,coins = [1,2,5]
가 주어졌을 때 1,2,5의 조합으로 15가 되게 합을 만들어야 한다. 이때 동전의 갯수가 최소한으로 되게 하고 그때의 갯수를 return하면 된다.
우선 부분 집합을 만들어야 하는데 이때 coins에서 하나의 원소가 수십번 뽑힐 수 도 있다. 15가 되기 전까지는 말이다.
이때 뽑히는 횟수를 level로 보고 level이 깊어지면서 부분집합이 만들어지는데 이 부분집합의 합을 sum이라고 하자.
또한 여기서 한 걸음 더 나아가 최소한의 동전의 갯수를 뽑았을때 무엇을 뽑았는지도 알아보도록하자.
coinComb[level] = coins[i]
라고 하면 dfs재귀가 호출될때마다 동전의 조합이 만들어질 것이다그럼 이제 구현해보자!
function showCoins(changes, coins) {
// 코인의 가장 작은 값으로 changes를 나누는게 가장 갯수가 많으므로. 최대 갯수를 구해주는 과정
let coinComb = Array.from({ length: changes / coins[0] }, () => 0);
let answerComb;
let answer = Number.MAX_SAFE_INTEGER;
function dfs(level, sum) {
if (sum > changes || level >= answer) return;
if (sum === changes) {
answer = Math.min(level, answer);
answerComb = coinComb.slice();
} else {
for (let i = 0; i < coins.length; i++) {
coinComb[level] = coins[i];
dfs(level + 1, sum + coins[i]);
coinComb[level] = 0;
}
}
}
dfs(0, 0);
return { answer, answerComb };
}
showCoins(3, [1, 2, 5]);
// answer: 3
// answerComb: (16) [0, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]