πŸ“š Language & CS knowledge/Algorithm & Data structure

23 동적 ν”„λ‘œκ·Έλž˜λ°

Daehyunii 2022. 8. 21. 17:29

23.1 동적 ν”„λ‘œκ·Έλž˜λ°

  동적 ν”„λ‘œκ·Έλž˜λ°μ΄λž€ λ³΅μž‘ν•œ 문제λ₯Ό κ°„λ‹¨ν•œ ν•˜μœ„ 문제의 λͺ¨μŒμœΌλ‘œ λΆ„λ¦¬ν•΄μ„œ 각 ν•˜μœ„ λ¬Έμ œλ“€μ„ ν’€μ–΄μ„œ κ·Έ 닡을 μ €μž₯ν•˜κ³  ν™œμš©ν•˜λŠ” λ°©μ‹μœΌλ‘œ 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 문제 ν•΄κ²° 방식이닀. 즉, 문제λ₯Ό ν•΄κ²°ν•˜λŠ”λ° μ‚¬μš©ν•  수 μžˆλŠ” μ ‘κ·Ό 방법 쀑 ν•˜λ‚˜μ΄λ‹€. λŒ€λΆ€λΆ„μ˜ 문제λ₯Ό 동적 ν”„λ‘œκ·Έλž˜λ°μœΌλ‘œ ν•΄κ²° ν•  μˆ˜λŠ” μ—†μ§€λ§Œ, 동적 ν”„λ‘œκ·Έλž˜λ°μœΌλ‘œ ν•΄κ²°ν•  수 μžˆλŠ” λ¬Έμ œλ“€μ— λŒ€ν•΄ 동적 ν”„λ‘œκ·Έλž˜λ°μœΌλ‘œ 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 경우 μ„±λŠ₯에 μžˆμ–΄μ„œ μ•„μ£Ό 큰 차이λ₯Ό κ°€μ Έμ˜¨λ‹€. λ‹€μ‹œ 말해 λŒ€λΆ€λΆ„μ˜ λ¬Έμ œμ— μ μš©ν•  수 μžˆλŠ” 것은 μ•„λ‹ˆμ§€λ§Œ μ‚¬μš©ν•  수 μžˆλŠ” κ²½μš°μ—λŠ” μ½”λ“œμ˜ 속도λ₯Ό 정말 많이 올릴 수 μžˆλ‹€.

 

23.2 동적 ν”„λ‘œκ·Έλž˜λ° ν™œμš© κ°€λŠ₯ 상황

  동적 ν”„λ‘œκ·Έλž˜λ°μ„ μ‚¬μš©ν•  수 μžˆλŠ”μ§€λ₯Ό ν™•μΈν•˜κΈ° μœ„ν•΄μ„œλŠ” 두 κ°€μ§€ 쑰건을 확인해야 ν•œλ‹€.

1) λ°˜λ³΅λ˜λŠ” ν•˜μœ„ λ¬Έμ œκ°€ μ‘΄μž¬ν•˜λŠ”κ°€?

2) 졜적 λΆ€λΆ„ ꡬ쑰가 μ‘΄μž¬ν•˜λŠ”κ°€?

 

  λ°˜λ³΅λ˜λŠ” ν•˜μœ„ λ¬Έμ œλž€ 해결이 ν•„μš”ν•œ λ¬Έμ œμ— μ–΄λ–€ λ°©μ‹μœΌλ‘œλ“  μ€‘μ²©λ˜λŠ” ν•˜μœ„ λ¬Έμ œλ“€μ΄ μžˆμ–΄μ•Ό ν•œλ‹€λŠ” 것이닀. 이 말은 ν•œ 문제λ₯Ό 더 μž‘μ€ λ¬Έμ œλ“€λ‘œ λ‚˜λˆŒ 수 있고, κ·Έ 쑰각듀 쀑 일뢀가 μž¬ν™œμš© κ°€λŠ₯ν•˜λ‹€λŠ” 말이닀. 각각의 쑰각이 λ‹€λ₯Έ λͺ¨μŠ΅μ΄λ©΄ μ•ˆλ˜κ³  μ—¬λŸ¬ 번 μž¬μ‚¬μš©ν•  수 μžˆμ–΄μ•Ό ν•œλ‹€. λŒ€ν‘œμ μΈ 예둜 ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄μ„ λ“€ 수 μžˆλ‹€. 

 

  졜적 λΆ€λΆ„ κ΅¬μ‘°λž€ ν•˜μœ„ 문제의 졜적 해닡을 ν†΅ν•΄μ„œ 더 큰 λ²”μ£Όμ˜ 문제의 졜적 해닡을 ꡬ성할 수 μžˆλŠ” 경우λ₯Ό λ§ν•œλ‹€. 예λ₯Ό λ“€λ©΄ μ„œμšΈμ—μ„œ 뢀산을 κ°€λŠ” μ΅œλ‹¨ 경둜λ₯Ό ꡬ해야 ν•œλ‹€κ³  ν•΄λ³΄μž. 이 λ¬Έμ œλŠ” (μ„œμšΈμ—μ„œ μ²œμ•ˆμœΌλ‘œ κ°€λŠ” μ΅œλ‹¨ 거리) + (μ²œμ•ˆμ—μ„œ λΆ€μ‚°μœΌλ‘œ κ°€λŠ” μ΅œλ‹¨ 거리)둜 ν•˜μœ„ 문제λ₯Ό λ‚˜λˆŒ 수 있고 각각의 ν•˜μœ„ 문제의 μ΅œλ‹¨ κ±°λ¦¬λ“€μ˜ 합이 (μ„œμšΈμ—μ„œ λΆ€μ‚°μœΌλ‘œ κ°€λŠ” μ΅œλ‹¨ 거리)κ°€ λ˜λŠ” 것을 λ§ν•œλ‹€.

 

23.3 ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄

  일반 μž¬κ·€ λ°©μ‹μœΌλ‘œ ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄

 

β—Žν”Όλ³΄λ‚˜μΉ˜ 곡식 

1) fib(n) = fib(n-1) + fib(n-2)

2) fib(2) = 1

3) fib(1) = 1

예λ₯Όλ“€μ–΄ fib(20)은 20번째 숫자의 값을 λ§ν•˜λŠ” 것이닀.

fib(6)은 숫자 8을 μ˜λ―Έν•œλ‹€.(1 + 1 + 2 + 3 + 5 + 8)

// 일반 μž¬κ·€ λ°©μ‹μ˜ ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄
function fib(n){
    if(n <= 2) return 1;
    return fib(n-1) + fib(n-2);
}

  μœ„μ˜ ν•¨μˆ˜μ²˜λŸΌ 일반 μž¬κ·€ λ°©μ‹μœΌλ‘œ ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄μ„ μž‘μ„±ν•  수 μžˆμ§€λ§Œ, O(2^N)의 μ‹œκ°„ λ³΅μž‘λ„λ₯Ό κ°€μ§€κΈ° λ•Œλ¬Έμ— 맀우 λΉ„νš¨μœ¨μ μ΄λ‹€. 쑰금만 μ „λ‹¬ν•˜λŠ” κ°’μ˜ 클수둝 처리 μ‹œκ°„μ΄ 맀우 μ˜€λž˜κ±Έλ¦°λ‹€. μ΄λŸ¬ν•œ 문제λ₯Ό ν•΄κ²°ν•  수 μžˆλŠ” 방법이 λ°”λ‘œ 동적 ν”„λ‘œκ·Έλž˜λ°μ΄λ‹€. ν”Όλ³΄λ‚˜μΉ˜ μˆ˜μ—΄μ˜ 경우 λ°˜λ³΅λ˜λŠ” ν•˜μœ„ λ¬Έμ œκ°€ μ‘΄μž¬ν•˜κ³  졜적 λΆ€λΆ„ ꡬ쑰λ₯Ό κ°–κΈ° λ•Œλ¬Έμ— 동적 ν”„λ‘œκ·Έλž˜λ°μœΌλ‘œ ν•΄κ²°ν•  수 μžˆλ‹€.

(ex fib(5) = fib(4) + fib(3) = fib(3) + fib(2) + fib(2) + fib(1))

 

23.4 Memo에 값을 μ €μž₯ν•˜λŠ” 방법(Memoization)

  μœ„μ˜ 일반 μž¬κ·€ λ°©μ‹μ˜ ν”Όλ³΄λ‚˜μΉ˜ ν•¨μˆ˜μ˜ λ¬Έμ œμ μ„ ν•΄κ²°ν•˜λŠ” λ°©λ²•μœΌλ‘œλŠ” ν•˜μœ„ 문제λ₯Ό ν•΄κ²°ν•˜κ³  λ‚˜μ˜¨ 값듀을 κΈ°μ–΅ν•΄ λ‘μ—ˆλ‹€κ°€ λ‹€μ‹œ ν™œμš©ν•˜λŠ” 것이닀. 예λ₯Ό λ“€λ©΄ fib(5)λ₯Ό κ΅¬ν• λ•ŒλŠ” fib(3)의 계산이 두 번 λ°˜λ³΅ν•˜κ²Œ λ˜λŠ”λ° 처음 fib(3)을 κ³„μ‚°ν–ˆμ„λ•Œ 이λ₯Ό κΈ°μ–΅ν•˜κ³  λ‹€μ‹œ fib(3)을 계산해야할 λ•Œ 미리 μ €μž₯ν•΄ 놓은 fib(3)의 값을 ν™œμš©ν•΄μ„œ λΉ λ₯΄κ²Œ κ³„μ‚°ν•˜λŠ” 것이닀. 핡심은 보톡 λ°°μ—΄μ΄λ‚˜ 객체둜 데이터λ₯Ό μ €μž₯ν•  ꡬ쑰λ₯Ό λ§Œλ“  λ‹€μŒ μ €μž₯ν•΄ 놓은 값듀을 ν™œμš©ν•΄μ•Ό ν•œλ‹€.

function fib(n, memo=[]){
  if(memo[n] !== undefined) return memo[n]
  if(n <= 2) return 1;
  var res = fib(n-1, memo) + fib(n-2, memo);
  memo[n] = res;
  return res;
}

23.5 Memoization을 ν™œμš©ν•΄μ„œ ν”Όλ³΄λ‚˜μΉ˜λ₯Ό κ΅¬ν˜„ν–ˆμ„ 경우의 λΉ…μ˜€ μ‹œκ°„ λ³΅μž‘λ„

1) 일반 μž¬κ·€ν˜• ν”Όλ³΄λ‚˜μΉ˜ : O(2^N)

2) λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ ν†΅ν•œ ν”Όλ³΄λ‚˜μΉ˜ : O(N)

 

23.6 Tabulation

  νƒ€λ·Έλ ˆμ΄μ…˜μ€ 루프와 같이 μˆœν™˜μ„ 톡해 μž‘μ—…ν•œλ‹€. λ©”λͺ¨μ΄μ œμ΄μ…˜κ³ΌλŠ” λ°˜λŒ€λ‘œ κ°€μž₯ μž‘μ€ ν•˜μœ„ 문제λ₯Ό ν‘Ό λ‹€μŒμ— κ·Έ κ²°κ³Όλ₯Ό μ €μž₯ν•œλ‹€. 즉, κ°€μž₯ λ°”λ‹₯에 μœ„μΉ˜ν•œ fib(1)λΆ€ν„° 계산을 ν•˜λ©΄μ„œ μ €μž₯ν•˜κ³  이λ₯Ό ν™œμš©ν•˜λ©° μ˜¬λΌκ°€λŠ” 방식이닀.

function fib(n){
    if(n <= 2) return 1;
    var fibNums = [0,1,1];
    for(var i = 3; i <= n; i++){
        fibNums[i] = fibNums[i-1] + fibNums[i-2];
    }
    return fibNums[n];
}