07 다이나믹 프로그래밍 (설명)

07 다이나믹 프로그래밍 (설명)

이것이 코딩 테스트다. with 파이썬 - 07 다이나믹 프로그래밍 설명

(이코테 2021 강의 몰아보기) 6. 다이나믹 프로그래밍

⭐ 나동빈님의 유튜브를 통해 확인해 주세요!!


다이나믹

다이나믹 프로그래밍은 메모리를 적절히 사용하여 수행 시간 효율성을 비약적으로 향상시카는 방법입니다.

이미 계산된 결과는 별도의 메모리 영역에 저장하여 다시 계산하지 않도록 합니다.

다이나믹 프로그래밍의 구현은 두 가지 방식으로 구성됩니다.

  • 탑다운: 위에서 부터 아래로
  • 보텀업: 아래에서부터 위로

다이나믹 프로그래밍은 문제가 다음의 조건을 만족할 때 사용할 수 있습니다.

  1. 최적 부분 구조
    • 큰 문제를 작은 문제로 나눌 수 있으며 작은 문제의 답을 모아서 큰 문제를 해결할 수 있습니다.
  2. 중복되는 부분 문제
    • 동일한 작은 문제를 반복적으로 해결합니다.

피보나치 수열

  • 피보나치 수열 다음과 같은 형태의 수열이며, 다이나믹 프로그래밍으로 효과적으로 계산할 수 있습니다.
1,1,2,3,5,8,13,21,34,55,89....

프로그래밍에서는 이러한 수열을 배열이나 리스트를 이용해 표현한다.

  • n번째 피보나치 수를 f(n)라고 할 때 4번째 피보나치 f(n)를 구하는 과정은 다음과 같다.
# 피보나치 함수(Fibonacci Function)을 재귀함수로 구현

def fibo(x):
	if x == 1 or x == 2:
		return 1
	return fibo(x-1) + fibo(x-2)

print(fibo(4))
  • 단순 재귀 함수로 피보나치 수열을 해결하면 지수 시간 복잡도를 가지게 된다.

  • 피보나치 수열의 시간 복잡도

    • 세타 표기법: θ(1.618…^N)
    • 빅오 표기법: O(2^N)

탑다운 VS 보텀업

탑다운(메모리제이션) 방식은 하향식이리고도 하며 보텀업 방식은 상향식이라고도 한다.

다이나믹 프로그램의 전형적인 형태는 보텀업 방식이다.

  • 결과 저장용 리스트는 DP 테이블 이라고 부른다.

엄밀히 말하면 메모이제이션은 이전에 계산된 결과를 일시적으로 기록해 놓는 넓은 개념을 의미한다.

  • 한 번 계산된 결과를 담아 놓기만 하고 다이나믹 프로그래밍을 위해 활용하지 않을 수도 있다.

탑다운 방식 - 메모이제이션

# 99 -> ... -> 2 까지 
# 한 번 계산된 결과를 메모이제이션(Memoization)하기 위한 리스트 초기화
d = [0] * 100

# 피보나치 함수(Fibonacci Function)를 재귀함수로 구현(탑다운 다이나믹 프로그래밍)
def fibo(x):
    # 종료 조건(1 혹은 2일 때 1을 반환)
    if x == 1 or x == 2:
        return 1
    # 이미 계산한 적 있는 문제라면 그대로 반환
    if d[x] != 0:
        return d[x]
    # 아직 계산하지 않은 문제라면 점화식에 따라서 피보나치 결과 반환
    d[x] = fibo(x - 1) + fibo(x - 2)
    return d[x]

print(fibo(99))

보텀업 방식 -DP 테이블

# 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화
d = [0] * 100

# 첫 번째 피보나치 수와 두 번째 피보나치 수는 1
d[1] = 1
d[2] = 1
n = 99

# 피보나치 함수(Fibonacci Function) 반복문으로 구햔(보텀업 다이나믹 프로그래밍)
for i in range(3, n + 1):
    d[i] = d[i - 1] + d[i - 2]

print(d[n])

다이나믹 프로그래밍 vs 분할 정복

  • 다이나믹 프로그래밍과 분할 정복은 모두 최적 부분 구조를 가질 때 사용할 수 있다.
    • 큰 문제를 작은 문제로 나눌 수 있으면 작은 문제의 답을 모아서 큰 문제를 해결할 수 있는 상황
  • 다이나믹 프로그래밍과 분할 정복의 차이점은 부분 문제의 중복이다.
    • 다이나믹 프로그래밍 문제에서는 각 부분 문제들이 서로 영향을 마치며 부분 문제가 종복된다.
    • 분할 정복 문제에서는 동일한 부분 문제가 반복적으로 계산되지 않는다.

다이나믹 프로그래밍 문제에 접근하는 방법

  • 주어진 문제가 다이나믹 프로그래밍 유형임을 파악하는 것이 중요하다.
  • 가장 먼저 그리디, 구현, 완전 탐색 등의 아이디어로 문제를 해결할 수 있는지 컴토할 수 있다.
    • 다른 알고리즘으로 풀이 방법이 떠오르지 않으면 다이나믹 프로그래밍을 고려해 보자.
  • 일단 재귀 함수로 비효율적인 완전 탐색 프로그램을 작성한 뒤에 (탑다운) 작은 문제에서 구한 답이 큰 문제에서 그대로 사용할 수 있으며, 코드를 개선하는 방법을 사용할 수 있다.

© 2021. All rights reserved.

Powered by Hydejack v9.1.6