백준 링크
https://www.acmicpc.net/problem/2294
문제 접근
우선 가치 K를 완성하기 위해 필요한 최소 동전 개수를 구하기 위해
완전 탐색 방식으로 접근을 시도 했다.
그림 설명
가치는 K이고 동전은 [1,2,3,4....N] 가정했을 때,
Top Down 방식으로 생각한다면, 가치 K가 되기 위해서는 K-1, K-2, K-3, .....K-N 에서 동전 한개를 추가했을 것이다.
따라서 트리형식이고, 이 경우의 시간복잡도는 O(N^K)이 된다.
그리고 시간 초과가 된다.
따라서 다른 방식을 생각해내야 했다.
그렇다면 DP는 어떨까?
가치 K가 되기 위해서는 dp[K-coin] + 1 과 dp[K] 의 최소값을 넣어주면 될것같았다.
이중 반복문을 사용하여,
첫번째 반복문 -> 모든 코인에 대해 순회
두번째 반복문 -> 가치에 대하여, 가치 = 해당 코인 ~ 최종 가치 K일 때까지 순회하면서 반복하면
작은 동전일 경우부터 차례대로 dp가 업데이트 될것이라고 생각했다.
✅ DP
문제 풀이
dp 배열
- dp[i]는 가치가 i를 만들 수 있는 가장 적은 동전의수를 의미한다.
- 우선 dp[0] = 0으로 초기화한다.
점화식
👉 dp[curVal] = min(dp[curVal - coin] + 1, dp[curVal])
- 현재 가치(curVal)까지의 최소 동전 개수는
- dp[현재 가치 - 코인 가치] + 1 혹은 dp[현재 가치]이다.
dp[현재 가치 - 코인 가치] + 1 의미
- 예를 들어 3이라는 가치를 만들기 위해 코인이 [1,2]가 있다고 가정하자.
코인 가치 1인 동전에 대해서
- 그럼 dp[3] 은 dp[2] + 1일 것이다. -> 가치가 2일 때의 최소 동전 개수 + 1
다음으로 코인 가치 2인 동전에 대해서
- dp[3] = dp[1] + 1이다.
- 추가적으로 이전 코인 가치 1일 때와 비교해서 더 적은 수를 dp[3]에 최종적으로 저장하면 된다.
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf8").trim().split("\n");
const [N, K] = input[0].split(" ").map(Number);
const coins = input.slice(1, N + 1).map(Number);
const dp = Array(K + 1).fill(Infinity);
dp[0] = 0;
coins.forEach((coin) => {
for (let curVal = coin; curVal <= K; curVal++) {
dp[curVal] = Math.min(dp[curVal - coin] + 1, dp[curVal]);
}
});
console.log(dp[K] === Infinity ? -1 : dp[K]);
코드 예시
예를 들어, 동전이 [2, 5]이고 K= 7인 경우,
초기: [0, Inf, Inf, Inf, Inf, Inf, Inf, Inf]
2원 동전 처리 후:
[0, Inf, 1, Inf, 2, Inf, 3, Inf]
5원 동전 처리 후:
[0, Inf, 1, Inf, 2, 1, 3, 2]
❌ DFS 문제 풀이 - 시간초과
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf8").trim().split("\n");
const [N, K] = input[0].split(" ").map(Number);
const sortOfCoins = input.slice(1, N + 1).map(Number);
let answer = Infinity;
function dfs(totalValue, numOfCoins) {
if (totalValue === 0) {
answer = Math.min(numOfCoins, answer);
return;
}
sortOfCoins.forEach((coin) => {
if (totalValue - coin >= 0) {
dfs(totalValue - coin, numOfCoins + 1);
}
});
}
dfs(K, 0);
console.log(answer);
'Algorithm' 카테고리의 다른 글
[JavaScript] 12904. A와 B (1) | 2025.03.27 |
---|---|
[JavaScript] 1446. 지름길 (1) | 2025.03.26 |
[JavaScript] 구간 합 구하기 5 (1) | 2025.03.21 |
[Javascript] 백준 1018. 체스판 다시 칠하기 (1) | 2025.03.14 |
[JavaScript] 백준 1535. 안녕 (1) | 2025.03.12 |