λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

Algorithm

[Algorithm] κ±°μŠ€λ¦„λˆ

πŸ“‹ 문제 

Finn은 νŽΈμ˜μ μ—μ„œ μ•Όκ°„ μ•„λ₯΄λ°”μ΄νŠΈλ₯Ό ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 야간에 μ†λ‹˜μ΄ λ„ˆλ¬΄ μ—†μ–΄ μ‹¬μ‹¬ν•œ Finn은 μ†λ‹˜λ“€κ»˜ κ±°μŠ€λ¦„λˆμ„ n 원을 쀄 λ•Œ λ°©λ²•μ˜ 경우의 수λ₯Ό κ΅¬ν•˜κΈ°λ‘œ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄μ„œ μ†λ‹˜κ»˜ 5원을 κ±°μŠ¬λŸ¬ μ€˜μ•Ό ν•˜κ³  1원, 2원, 5원이 μžˆλ‹€λ©΄ λ‹€μŒκ³Ό κ°™μ΄ 4κ°€μ§€ λ°©λ²•μœΌλ‘œ 5원을 κ±°μŠ¬λŸ¬ μ€„ μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.

 

  • 1원을 5개 μ‚¬μš©ν•΄μ„œ 거슬러 μ€€λ‹€.
  • 1원을 3개 μ‚¬μš©ν•˜κ³ , 2원을 1개 μ‚¬μš©ν•΄μ„œ κ±°μŠ¬λŸ¬ μ€€λ‹€.
  • 1원을 1개 μ‚¬μš©ν•˜κ³ , 2원을 2개 μ‚¬μš©ν•΄μ„œ κ±°μŠ¬λŸ¬ μ€€λ‹€.
  • 5원을 1개 μ‚¬μš©ν•΄μ„œ κ±°μŠ¬λŸ¬ μ€€λ‹€.

거슬러 μ€˜μ•Ό ν•˜λŠ” κΈˆμ•‘ nκ³Ό Finn이 ν˜„μž¬ λ³΄μœ ν•˜κ³  μžˆλŠ” λˆμ˜ μ’…λ₯˜ moneyκ°€ λ§€κ°œλ³€μˆ˜λ‘œ μ£Όμ–΄μ§ˆ λ•Œ, Finn이 n μ›μ„ κ±°μŠ¬λŸ¬ μ€„ λ°©λ²•μ˜ μˆ˜λ₯Ό return ν•˜λ„둝 solution ν•¨μˆ˜λ₯Ό μ™„μ„±ν•΄ μ£Όμ„Έμš”.

 

μ œν•œ 사항

  • n은 100,000 μ΄ν•˜μ˜ μžμ—°μˆ˜μž…λ‹ˆλ‹€.
  • 화폐 λ‹¨μœ„λŠ” 100μ’…λ₯˜ μ΄ν•˜μž…λ‹ˆλ‹€.
  • λͺ¨λ“  ν™”νλŠ” λ¬΄ν•œν•˜κ²Œ μžˆλ‹€κ³  κ°€μ •ν•©λ‹ˆλ‹€.
  • 정닡이 컀질 수 μžˆμœΌλ‹ˆ, 1,000,000,007둜 λ‚˜λˆˆ λ‚˜λ¨Έμ§€λ₯Ό return ν•΄μ£Όμ„Έμš”.

 

μž…μΆœλ ₯ 예

5 [1,2,5] 4

 

✏️ 풀이

문제λ₯Ό 보고 DP 문제 같은데..? λΌλŠ” 생각을 λ¨Όμ € ν–ˆλ˜ 것 κ°™λ‹€. λͺ¨λ“  경우의 수λ₯Ό 계속 μ°ΎκΈ°μ—λŠ” 무쑰건 μ‹œκ°„μ΄ˆκ³Όκ°€ λ‚  것 κ°™κ³  μ°¨κ·Όμ°¨κ·Ό λ©”λͺ¨μ΄μ œμ΄μ…˜ 해놓은 값을 μ‚¬μš©ν•΄μ•Ό ν•  것 κ°™μ€λ°λΌλŠ” 생각을 ν–ˆλ‹€.

 

 

λ¨Όμ € DP 배열을 λ§Œλ“€μ–΄μ£Όλ©΄μ„œ 점화식을 생각해봀닀. λ‚΄κ°€ μ„Έμš΄ 점화식은 λ‹€μŒκ³Ό κ°™λ‹€.

DP[i] = i원을 λ§Œλ“€ 수 μžˆλŠ” κ°€μ§“μˆ˜

 

μ²˜μŒμ— money 배열에 λ“€μ–΄μžˆλŠ” 값은 자기 μžμ‹ μ΄λ―€λ‘œ DP[money[i]]λŠ” 1둜 μ΄ˆκΈ°ν™”ν•΄μ•Ό ν•œλ‹€λŠ” 생각에 money 배열을 λŒλ©΄μ„œ dp[money[i]] += 1을 해쀬닀. 그리고 생각이 λ“ κ²Œ 자기 μžμ‹ λ³΄λ‹€ μž‘μ€ κΈˆμ•‘μ΄λΌλ©΄ λ§Œλ“€ 수 μ—†λŠ” κΈˆμ•‘μ΄λΌλŠ” 생각에 λ°˜λ³΅λ¬Έμ„ μΆ©μ²©ν•˜μ—¬ 자기 μžμ‹ λΆ€ν„° λͺ©ν‘œλ‘œ ν•œ κΈˆμ•‘κΉŒμ§€ κ°€λ©΄μ„œ i원을 λ§Œλ“€ 수 μžˆλŠ” κ²½μš°μ— ν˜„μž¬ κΈˆμ•‘μ„ ν¬ν•¨ν•˜λ©° λ§Œλ“€ 수 μžˆλŠ” κ°€μ§€μˆ˜λ₯Ό 더해쀬닀.

 

문제의 μ˜ˆμ‹œλ₯Ό 예λ₯Ό λ“€μ–΄ ν˜„μž¬ 돈의 μ’…λ₯˜κ°€ 2원이라면 2원뢀터 5μ›κΉŒμ§€ 인덱슀둜 μ¦κ°€μ‹œν‚€λ©΄μ„œ λ‹€μŒκ³Ό 같은 μž‘μ—…μ„ ν•˜λ„λ‘ ν–ˆλ‹€.

 

  • dp[2] = dp[2] + dp[2-2];
  • dp[3] = dp[3] + dp[3-2];
  • dp[4] = dp[4] + dp[4-2];
  • dp[5] = dp[5] + dp[5-2];

이 과정을 λͺ¨λ‘ μ’…λ£Œν•˜κ²Œ 되면 dp[n] (dp λ°°μ—΄μ˜ λ§ˆμ§€λ§‰ μš”μ†Œ)λŠ” 결과적으둜 μ΄μ „μ˜ κ°€λŠ₯ν•œ λͺ¨λ“  κ°€μ§€μˆ˜λ₯Ό λ”ν•œ 값이 λ˜λ―€λ‘œ n원을 λ§Œλ“€ 수 μžˆλŠ” κ°€μ§€μˆ˜κ°€ λœλ‹€.

 

⌨️ μ½”λ“œ

function solution(n, money) {
  const dp = new Array(n + 1).fill(0);

  for (const m of money) {
    dp[m] += 1;
    for (let i = m; i <= n; i++) dp[i] += dp[i - m];
  }

  return dp[n] % 1000000007;
}