Algorithm/μΈν”„λŸ°(inflearn)

[JavaScript/section 10] 04 - λ™μ „κ΅ν™˜

_μ„±ν˜Έ_ 2022. 12. 22. 17:27
728x90
λ°˜μ‘ν˜•

πŸ“Œ λ™μ „κ΅ν™˜(냅색 μ•Œκ³ λ¦¬μ¦˜)

λ‹€μŒκ³Ό 같이 μ—¬λŸ¬ λ‹¨μœ„μ˜ 동전듀이 μ£Όμ–΄μ Έ μžˆμ„λ•Œ κ±°μŠ€λ¦„λˆμ„ κ°€μž₯ 적은 수의 λ™μ „μœΌλ‘œ κ΅ν™˜ν•΄μ£Όλ €λ©΄ μ–΄λ–»κ²Œ μ£Όλ©΄ λ˜λŠ”κ°€? 각 λ‹¨μœ„μ˜ 동전은 λ¬΄ν•œμ • μ“Έ 수 μžˆλ‹€.

 

μž…λ ₯μ„€λͺ…

첫 번째 μ€„μ—λŠ” λ™μ „μ˜ μ’…λ₯˜κ°œμˆ˜ N(1<=N<=12)이 주어진닀. 두 번째 μ€„μ—λŠ” N개의 λ™μ „μ˜ μ’…λ₯˜κ°€ 주어지고, κ·Έ λ‹€μŒμ€„μ— 거슬러 쀄 κΈˆμ•‘ M(1<=M<=500)이 주어진닀.

각 λ™μ „μ˜ μ’…λ₯˜λŠ” 100원을 λ„˜μ§€ μ•ŠλŠ”λ‹€.

좜λ ₯μ„€λͺ…

첫 번째 쀄에 거슬러 쀄 λ™μ „μ˜ μ΅œμ†Œκ°œμˆ˜λ₯Ό 좜λ ₯ν•œλ‹€.

μž…λ ₯예제 좜λ ₯예제
3
1 2 5
15
3 (5 5 5)

 

πŸ“ 풀이 방법

DFSλ₯Ό μ‚¬μš©ν•΄ μΆ©λΆ„νžˆ ν•΄κ²°ν•  수 μžˆλŠ” λ¬Έμ œμ΄μ§€λ§Œ N이 100 이상, M이 10000 μ΄μƒμœΌλ‘œ 컀진닀면 μ‹œκ°„μ΄ 였래 κ±Έλ¦°λ‹€λŠ” λ¬Έμ œκ°€ λ°œμƒν•œλ‹€.

DP λ¬Έμ œμ—μ„œ 유λͺ…ν•œ 냅색 μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•΄ μ΄λŸ¬ν•œ 문제λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€.

 

1μ›μœΌλ‘œλ§Œ κ±°μŠ€λ¦„λˆμ„ κ΅ν™˜ν•΄μ£ΌλŠ” 경우

 

1원, 2원을 ν•¨κ»˜ μ‚¬μš©ν•˜μ—¬ κ±°μŠ€λ¦„λˆμ„ κ΅ν™˜ν•΄μ£ΌλŠ” 경우

  • dy[j] - j κΈˆμ•‘μ„ κ±°μŠ¬λŸ¬μ£ΌλŠ”λ° μ‚¬μš©λœ μ΅œμ†Œ λ™μ „μ˜ 개수
  • μœ„μ—μ„œ 풀이 κ³Όμ • 쀑 ν•œ μž₯면을 μ˜ˆμ‹œλ‘œ λ³΄μ—¬μ£Όμ—ˆλ‹€. 이와 같은 과정을 λ°˜λ³΅ν•œ ν›„ dy λ°°μ—΄μ˜ λ§ˆμ§€λ§‰ μ›μ†Œλ₯Ό answer λ³€μˆ˜μ— ν• λ‹Ήν•΄μ£Όλ©΄ λœλ‹€. 
function solution(m, coin) {
  let answer = 0;
  // μ΅œμ†Œ λ™μ „μ˜ 개수λ₯Ό κ΅¬ν•˜λŠ” λ¬Έμ œμ΄λ―€λ‘œ μ΅œλŒ€ λ™μ „μ˜ 개수 500(1 x 500)보닀 큰 1000으둜 μ΄ˆκΈ°ν™”
  let dy = Array.from({ length: m + 1 }, () => 1000);
  // 0원을 κ±°μŠ¬λŸ¬μ£ΌλŠ”λ° μ‚¬μš©λ˜λŠ” λ™μ „μ˜ κ°œμˆ˜λŠ” μ—†μœΌλ―€λ‘œ 0으둜 μ΄ˆκΈ°ν™”
  dy[0] = 0;

  for (let i = 0; i < coin.length; i++) {
    for (let j = coin[i]; j <= m; j++) {
      dy[j] = Math.min(dy[j], dy[j - coin[i]] + 1);
    }
  }

  answer = dy[m];  
  return answer;
}

let arr = [1, 2, 5];
console.log(solution(15, arr));