동적계획법(DP, Dynamic Programming)

2025. 5. 13. 17:30·CS/알고리즘 & 자료구조
728x90
반응형

1. 왜 만들어 졌을까?

어원(When)

  • Dynamic: 시간에 따라 변하는 걸 의미하는 것이 아님!
  • Programming: 코드 작성이 아니라, 계획(Plan)을 짠다는 의미

즉, 유동적으로 결정하는 계획 정도의 뜻

누가 만들었나?

    • Richard Bellman(리처드 벨만), 1950년대
    • 미 국방성 프로젝트 중 최적화 문제를 해결하기 위해 개발
    •  
    •  

왜? ‘Dynamic Programming’이라 이름 붙였나?벨만의 유명한 일화에 따르면:

내가 일하던 국방 프로젝트는 ‘수학’이나 ‘과학’이라는 단어에 거부감을 가진 관리들이 있었지
그래서 그들이 이해 못할 단어를 골라야 했어. 그래서 ‘다이내믹 프로그래밍’이라고 불렀지
즉, 본래 의미보다 정치적 이유(!)로 지어진 네이밍…

어떤 알고리즘이야?

큰 문제를 작은 문제를 나눠서 푼 뒤, 그 결과를 재사용하여 전체 문제를 효율적으로 해결하는 기법
즉, 중복되는 연산을 저장하여 시간 복잡도를 줄이는 방법

 


DP가 필요한 상황

  • 문제를 작은 하위 문제로 분할 가능한지
  • 하위 문제의 결과가 여러번 반복적으로 사용되는지

키워드

  • 피보나치 수열
  • 최장 공통 부분 수열(LCS)
  • 배낭 문제
  • 계단 오르기, 동전 교환 등

피보나치 예시

// f(n) = f(n-1) + f(n-2),  f(0) = 0, f(1) = 1
int fib(int n) {
    if (n <= 1) return n;
    return fib(n - 1) + fib(n - 2);
}

해결 고민: 어떻게 중복 계산을 줄일까?

→ 탑다운
→ 바텀업
→ 누적계산

해결 방법 선택

1. Top-down (재귀 + 메모이제이션)

int[] memo = new int[100];

int fib(int n) {
    if (n <= 1) return n;
    if (memo[n] != 0) return memo[n];
    return memo[n] = fib(n - 1) + fib(n - 2);
}

2. Bottom-up

int fib(int n) {
    if (n <= 1) return n;
    int[] dp = new int[n + 1];
    dp[0] = 0;
    dp[1] = 1;
    for (int i = 2; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 2];
    }
    return dp[n];
}

시간 복잡도를 고려하지 않고 잘못된 방식 사용

예시: 하향식 재귀만 쓰고 캐싱을 안한 경우

int fib(int n) {
    if (n <= 1) return n;
    return fib(n - 1) + fib(n - 2);
}
  • 재귀로 간결해 보이나
  • fib(5)를 호출하면 fib(3), fib(2) 등이 여러 번 계산됨
  • 결과: 시간복잡도는 O(2^n) → 매우 비효율적

올바른 DP 사고방식 흐름

  1. 문제를 하위 문제로 쪼갤 수 있는가?(예: n = n -1 + n-2)
  2. 하위 문제의 결과가 중복되어 사용되는가?(예: fib(3)이 여러 번 등장)
  3. 결과를 캐싱하거나 반복문으로 누적할 수 있는가?
  4. 시간 복잡도가 실제로 줄어드는지 확인(예: O(n)인지 확인)
728x90
반응형
저작자표시 비영리 (새창열림)

'CS > 알고리즘 & 자료구조' 카테고리의 다른 글

Binary Gap 문제  (1) 2025.05.21
벽 부수고 이동하기  (0) 2025.05.13
자료구조 선택 (HashSet vs BitSet)  (0) 2025.05.10
수 찾기  (1) 2025.05.10
덱(Deque) 보다 큐(Queue)와 스택(Stack)이 더 좋은 경우?  (0) 2025.03.11
'CS/알고리즘 & 자료구조' 카테고리의 다른 글
  • Binary Gap 문제
  • 벽 부수고 이동하기
  • 자료구조 선택 (HashSet vs BitSet)
  • 수 찾기
크크크크
크크크크
공뷰를 합시다.
    반응형
  • 크크크크
    Tom's Note
    크크크크
  • 전체
    오늘
    어제
    • 분류 전체보기 (130)
      • IT 지식 (6)
      • CS (66)
        • 알고리즘 & 자료구조 (19)
        • 운영체제 (41)
        • 네트워크 (1)
        • 데이터베이스 (5)
      • 보안 (6)
      • SW 공학 & 프로그래밍 언어 (5)
        • Java (28)
        • 디자인 패턴 (1)
        • 형상관리 (2)
        • 톰캣(WAS) (2)
        • SW 방법론 (3)
        • 스프링부트 (5)
      • 시스템 설계 (4)
        • Docker (2)
      • 자격증 (2)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      docker
      DI
      java
      apropos
      /etc/passwd
      man
      알고리즘
      whereis
      단반향
      chmod
      불변
      passwd
      REST API
      Chage
      문제해결
      which
      분석기법
      2차
      ADsP
      암호설정
      1급
      whatis
      usermod
      자바
      스프링부트
      cifs
      비트연산
      리눅스
      su
      DTO
    • 최근 댓글

    • 최근 글

    • 250x250
    • hELLO· Designed By정상우.v4.10.3
    크크크크
    동적계획법(DP, Dynamic Programming)
    상단으로

    티스토리툴바