Algorithm

Dynamic Programming (기초 개념)

주인장 꼬비 2022. 12. 3. 00:35

Dynamic Programming 이란?

복잡한 문제를 더 간단한 하위 문제의 모음으로 쪼개서 각 하위 문제들을 풀어서 그 답을 저장하는 방식으로 문제를 푸는 것

대부분의 문제에 적용할 수 있는 것은 아니지만 사용할 수 있는 경우에는 코드의 속도를 많이 향상시켜준다.

=> 최적의 해답을 찾아내는 것

 

Dynamic Programming 을 사용하기 위한 전제 조건

1. 최적 부분 구조가 존재하는가

2. 반복되는 하위 문제가 있는가

 

반복되는 하위 문제란?

한 문제를 더 작은 문제들로 나눌 수 있고, 그 조각들 중 일부가 재활용 가능하다는 말.

ex) Fibonacci Sequence

// Big O : O(2^n)
function fib(n) {
  if (n <= 2) return 1;

  return fib(n - 1) + fib(n - 2);
}

 

최적 부분 구조란?

하위 문제의 최적 해답을 통해서 더 큰 범주의 문제의 최적 해답을 구성할 수 있는 경우 해당 문제가 최적 부분 구조를 가지는 것

ex) A, B, C, D 가 있고 A 에서 D로 갈떄 A -> B -> C -> D 가 아닐 수 있다는 것. 

 

 

Dynamic Programming example - Fibonacci

TIP 

1. Fib(n) = Fib(n-1) + Fib(n-2)

2. Fib(2) is 1

3. Fib(1) is 1

 

Memoization

배열이나 객체인 데이터를 저장할 구조를 만든 다음에 시간이 오래 걸리는 함수를 실행하는 것. (메모 역할)

// Big O : O(n)
function fib(n, memo = []) {
  if (memo[n]) return memo[n];
  if (n <= 2) return 1;

  const res = fib(n - 1, memo) + fib(n - 2, memo);
  memo[n] = res;
  return res;
}

 

Tabulation

테이블에 이전 결과를 저장하는 것으로 보통 배열을 사용한다. 재귀를 사용하는 Memoization에 비해 공간복잡도다 낫다.

(Memoization에서 stack이 넘치는 오류가 발생할 수 있다. = Maximum call stack size exceeded)

function fib(n) {
  if (n <= 2) return 1;
  let fibNums = [0, 1, 1];

  for (let i = 3; i <= n; i++) {
    fibNums[i] = fibNums[i - 1] + fibNums[i - 2];
  }
  return fibNums[n];
}

 

 

'Algorithm' 카테고리의 다른 글

만나본 DP 문제 풀이 유형  (0) 2023.01.01
Dynamic Programming (백준 정리글)  (0) 2023.01.01
백준 문제 추천  (0) 2022.10.30
BFS(Breadth First Search) & DFS(Depth First Search)  (0) 2022.09.24
BST (Binary Search Tree)  (0) 2022.09.24