the others/Algorithm

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

ciocio 2021. 10. 11. 14:33

πŸ“Œ  동적 ν”„λ‘œκ·Έλž˜λ°μ΄λž€ ?

 

동적 ν”„λ‘œκ·Έλž˜λ°μ΄λΌκ³  ν•΄μ„œ λ™μ μœΌλ‘œ ?!? ν”„λ‘œκ·Έλž˜λ°μ΄ μ΄λ£¨μ–΄μ§€λŠ” 건 μ•„λ‹ˆλ‹€ γ…‹γ…‹γ…‹

큰 문제λ₯Ό μž‘μ€ 문제둜 λ‚˜λˆ„μ–΄ ν‘ΈλŠ” 법을 λ§ν•œλ‹€.  ->  그럼 λΆ„ν•  정볡 μ•„λ‹Œκ°€ ?

 

πŸ“  Divide and Conquer λΆ„ν•  μ •λ³΅μ΄λž€ ?

λΆ„ν•  정볡도 큰 문제λ₯Ό μž‘μ€ 문제둜 λ‚˜λˆ„μ–΄ ν‘ΈλŠ” 법이닀.
κ·ΈλŸ¬λ‚˜ 동적 ν”„λ‘œκ·Έλž˜λ°κ³ΌλŠ” 큰 차이점이 μžˆλ‹€.
λΆ„ν•  정볡은, " μž‘μ€ 문제 " μ—μ„œ 반볡이 μΌμ–΄λ‚˜μ§€ μ•ŠλŠ”λ‹€.
동적 ν”„λ‘œκ·Έλž˜λ°μ€, " μž‘μ€ 문제 " μ—μ„œ 반볡이 μΌμ–΄λ‚œλ‹€.  ->  λΆˆν•„μš”ν•œ 일듀이 반볡적으둜 μΌμ–΄λ‚œλ‹€.

 

즉, λΆ„ν•  정볡은 μ§„μ§œ 큰 문제λ₯Ό μ—¬λŸ¬ 개둜 μž‘κ²Œ μž‘κ²Œ λ‚˜λˆ μ„œ ν‘ΈλŠ” 방식이라면,

동적 ν”„λ‘œκ·Έλž˜λ°μ€ μ–΄μ§œν”Ό λ°˜λ³΅λ˜λŠ” μž‘μ€ λ¬Έμ œλ“€μ„ ν•œ 곳에 λ¬Άμ–΄ λ†“κ±°λ‚˜(?) 기둝(?) ν•˜λŠ” μ‹μœΌλ‘œ 

λΆˆν•„μš”ν•œ λ°˜λ³΅λ“€μ„ μ€„μ΄λ©΄μ„œ 큰 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 방식을 λ§ν•œλ‹€.

 

πŸ“  Memoization λ©”λͺ¨μ΄μ œμ΄μ…˜μ΄λž€ ?

동적 ν”„λ‘œκ·Έλž˜λ°μ—μ„œ λ°˜λ³΅λ˜λŠ” μž‘μ€ λ¬Έμ œλ“€μ„ " 기둝 " 을 톡해 λΆˆν•„μš”ν•œ λ°˜λ³΅μ„ ν•΄κ²°ν•˜λŠ” 방식이닀.
ν•œ 번 κ³„μ‚°ν•œ μž‘μ€ 문제의 값은 μž¬μ‚¬μš©ν•˜κΈ° ν•œ 곳에 μ €μž₯(기둝) ν•΄λ†“λŠ”λ‹€.

 

// memoization μ˜ˆμ‹œ

function memoization_fib(n){
  let memo = [];
  
  memo[0] = 0;
  memo[1] = 1;
  
  if(n <= 1) return memo[n];
  
  for(let i=2; i<n; i++){
  	memo[n] = memo[n-1] + memo[n-2]
  }
  
  return memo[n];
}

// f(2) = f(1) + f(0)
// f(3) = f(2) + f(1) = f(1) + f(0) + f(1)
// f(4) = f(3) + f(2) = f(2) + f(1) + f(1) + f(0) = f(1) + f(0) + f(1) + f(1) + f(0)

// -> μž‘μ€ λ¬Έμ œλ“€μ΄ λ°˜λ³΅λœλ‹€.
// -> 같은 λ¬Έμ œλŠ” ꡬ할 λ•Œλ§ˆλ‹€ 정닡이 κ°™λ‹€.

// λ°˜λ³΅λ˜λŠ” 값듀을 배열에 μ €μž₯해두고 ν•„μš”ν•  λ•Œλ§ˆλ‹€ κΊΌλ‚΄ μ“΄λ‹€. ^__^

 

 

πŸ“Œ  κ΅¬ν˜„ 방법 : Bottom-up & Top-down

 

β—Ύ  Bottom-up

 

// Bottom-up 
// μ•„λž˜λΆ€ν„° μ°¨κ·Όμ°¨κ·Ό, 값을 ꡬ해 λ‚˜κ°€λŠ” 방식이닀. μ•„λž˜ -> μœ„

// λŒ€λΆ€λΆ„μ˜ 반볡문이 Bottom-up 방식에 ν•΄λ‹Ήλœλ‹€.

function fibo_bottom_up(n){
  if(n <= 1) return n;
  
  let front = 0;
  let next  = 1;
  
  for(let i=1; i<n; i++){
  	
    let sum = front + next;
    front = next;
    next = sum;
    
  }
  
  return sum;
}

// fibo_bottom_up(6)을 κ΅¬ν•œλ‹€κ³  κ°€μ •ν–ˆμ„ λ•Œ,

// i=1, sum=1, front=1, next=1
// i=2, sum=2, front=1, next=2
// i=3, sum=3, front=2, next=3
// i=4, sum=5, front=3, next=5
// i=5, sum=8, front=5, next=8     returnλ˜λŠ” 값은 8이닀.

// μ•„λž˜λΆ€ν„° μ°¨λ‘€λŒ€λ‘œ μ°¨κ·Όμ°¨κ·Ό μ˜¬λΌμ˜€λŠ” 과정을 확인할 수 μžˆλ‹€.

 

 

β—Ύ  Top-down

 

// Top-down
// 큰 문제λ₯Ό ν’€ λ•Œ μž‘μ€ 문제λ₯Ό ν’€μ–΄μ•Ό 값이 λ‚˜μ˜¨λ‹€λŠ” κ±Έ μ•Œμ•„μ•Ό γ…‹γ…‹ κ·Έμ œμ„œμ•Ό μž‘μ€ 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 방식이닀.
// μ°¨κ·Όμ°¨κ·Ό 방식 μ ˆλŒ€ μ•„λ‹˜ X ν•„μš”ν•œ μž‘μ€ λ¬Έμ œλ“€λ§Œ ν•΄κ²°ν•˜κ³  닡을 λ„μΆœ ! μœ„ -> μ•„λž˜

// λŒ€λΆ€λΆ„μ˜ μž¬κ·€ ν•¨μˆ˜κ°€ Top-down 방식에 ν•΄λ‹Ήλœλ‹€
// fibo_top_down(6)을 κ΅¬ν•˜κΈ° μœ„ν•΄ fibo_top_down(5)와 fibo_top_down(4)λ₯Ό κ΅¬ν•˜κΈ° μ‹œμž‘ν•¨

function fibo_top_down_recur(n){
  if(n <= 1) return n;
  return fibo_top_down_recur(n-1) + fibo_top_down_recur(n-2);
}


// μš°λ¦¬λŠ” Dynamic Programming 을 배우고 μžˆμœΌλ‹ˆ,
// 이미 κ΅¬ν•œ 값을 또 κ΅¬ν•˜λŠ” λ‚­λΉ„λŠ” ν•˜μ§€ μ•Šλ„λ‘ μ½”λ“œλ₯Ό 짜자 !~ :)

function fibo_top_down_dp(n){
  let memo = [0, 1];
  
  if(n <= 1) return memo[n];
  
  for(let i=2; i<n; i++){
  	memo[n] = memo[n-1] + memo[n-2]
  }
  
  return memo[n];
}

 

 

πŸ“Œ  동적 ν”„λ‘œκ·Έλž˜λ°μ„ ν™œμš©ν•œ 문제 풀이 μ˜ˆμ‹œ

 

2021.10.12 - [개발 곡뢀/Algorithm] - μžλ°”μŠ€ν¬λ¦½νŠΈ ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ κ±°μŠ€λ¦„λˆ 문제 풀이

 

μžλ°”μŠ€ν¬λ¦½νŠΈ ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ κ±°μŠ€λ¦„λˆ 문제 풀이

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

code-designer.tistory.com

 

λ°˜μ‘ν˜•