일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 성능
- php
- GCM 번역
- 푸시 번역
- APNS
- 도메인 주도 개발
- 자바스크립트
- ddd
- 웹사이트성능
- 푸시
- 카프카
- git
- Design Pattern
- graphql
- nginx설정
- nginx
- gcm 푸시 번역
- 페이스북 번역
- notification
- 웹사이트 성능
- 카프카 트랜잭션
- 디자인패턴
- 웹사이트최적화기법
- GCM
- Java
- JPA
- nginx설치
- Push
- kafka
Archives
- Today
- Total
간단한 개발관련 내용
[DP] 동적 프로그래밍 또는 동적 계획법(Dynamic Programming) 본문
Computer Science/Algorithm & Etcs...
[DP] 동적 프로그래밍 또는 동적 계획법(Dynamic Programming)
vincenzo.dev.82 2025. 1. 22. 17:47반응형
동적 프로그래밍 (Dynamic Programming, DP)
동적 프로그래밍은 복잡한 문제를 작은 하위 문제로 나누고, 각 하위 문제를 한 번만 풀어 그 결과를 재사용함으로써 전체 문제를 효율적으로 해결하는 알고리즘 기법입니다. 이는 재귀적 접근법(분할정복)과 메모이제이션(결과 저장)을 결합한 방식으로, 중복 계산을 줄이는 것이 핵심입니다.
동적 프로그래밍의 특징
- 최적 부분 구조 (Optimal Substructure): 문제를 더 작은 하위 문제로 나눌 수 있으며, 이 하위 문제들의 해결 방법을 조합해 전체 문제를 해결할 수 있어야 합니다.
- 중복되는 하위 문제 (Overlapping Subproblems): 동일한 하위 문제가 여러 번 반복되어 계산될 경우, 이전 계산 결과를 저장해 재사용할 수 있습니다.
동적 프로그래밍의 구현 방식
- 메모이제이션 (Memoization): 재귀 방식으로 구현되며, 계산된 결과를 테이블(배열, 맵 등)에 저장해 중복 계산을 방지합니다.
- 탑다운 (Top-Down): 큰 문제에서 시작해 작은 문제를 해결하는 방식 (재귀적).
- 보텀업 (Bottom-Up): 작은 문제부터 차례로 해결해 큰 문제로 확장하는 방식 (반복적).
DP과 재귀적 호출의 차이점?
하향식(Top-down) vs 상향식(Bottom-up) 접근
재귀적 호출은 주로 하향식(top-down) 접근 방식을 사용합니다. 즉, 큰 문제를 작은 하위 문제로 나누어 해결하는 방식입니다. 반면에 동적 계획법은 주로 상향식(bottom-up) 접근 방식을 사용합니다. 작은 하위 문제들부터 시작하여 그 결과를 저장하고, 이를 이용하여 점진적으로 큰 문제의 해를 구해나갑니다.
메모이제이션(Memoization)
동적 계획법은 중복되는 계산 결과를 저장하는 메모리 기법인 메모이제이션을 사용합니다. 이를 통해 이전에 계산한 값을 캐시하고, 다시 필요할 때 해당 값을 가져와 재사용합니다. 이는 재귀적 호출에서의 중복 계산을 방지하고 계산 속도를 향상시킵니다.
간단한 예시: 피보나치 수열
피보나치 수열은 아래와 같이 정의됩니다:
1. 재귀적 접근 (비효율적):
def fib_recursive(n):
if n == 0:
return 0
elif n == 1:
return 1
return fib_recursive(n-1) + fib_recursive(n-2)
print(fib_recursive(10)) # 55
- 문제점: 동일한 값을 여러 번 계산하여 시간 복잡도가 O(2^n)에 가까움.
2. 동적 프로그래밍 (메모이제이션):
def fib_memoization(n, memo={}):
if n in memo:
return memo[n]
if n == 0:
return 0
elif n == 1:
return 1
memo[n] = fib_memoization(n-1, memo) + fib_memoization(n-2, memo)
return memo[n]
print(fib_memoization(10)) # 55
- 장점: 중복 계산을 방지하여 시간 복잡도가 O(n) 으로 줄어듦.
3. 동적 프로그래밍 (보텀업):
def fib_bottom_up(n):
if n == 0:
return 0
elif n == 1:
return 1
dp = [0] * (n + 1)
dp[1] = 1
for i in range(2, n + 1):
dp[i] = dp[i-1] + dp[i-2]
return dp[n]
print(fib_bottom_up(10)) # 55
- 장점: 반복문을 사용해 추가적인 재귀 호출을 피하며 O(n) 시간 복잡도를 가짐.
응용 분야
- 최적 경로 탐색: 예) 다익스트라 알고리즘, 벨만-포드 알고리즘.
- 배낭 문제 (Knapsack Problem): 한정된 용량의 배낭에 최대 가치를 담는 문제.
- 문자열 문제: 예) 문자열 정렬, 편집 거리(Edit Distance).
- 게임 이론 및 확률 문제: 예) 님 게임(Nim Game), 확률 계산.
반응형