- 참치군
- ?
- stalk.io
- :: 2013년, 스리는 여섯살
- 웹 강좌
- 점프 투 파이썬
- 요니나의 대학생 재테크
- This is CS50
- 애자일 이야기
- isao의 IT,게임번역소
- 소프트웨어 이야기
- Color Scripter
- 어디를 가든지 마음을 다해 가라
- VisuAlgo
- 서울대 평생교육원
- 몽환
- RegExr: Learn, Build, & Test R…
- Hello, Stranger :D
- I Like Exploit
- Z3alous Security Story
- Project Euler
- Blog
- pieces of code
- window 쪼물딱 거리기
- IT - Informatics Alphabet
- rop
- 국제 정보교육센터 I2sec 대구 1기
- This is the moment. :)
- blackmoon
- z3alous는 세상에 소리 z3alous~
- Acord
- FORENSIC-PROOF
- 어셈블리
- Outsider's Dev Story
- Open Tutorials
- 코드라이언
- 컴퓨터 그래픽스와 3D 프린팅
- HACKABILITY
- Lee, Jae-Hong
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 레지스터
- Wireshark
- ubuntu
- Hello World
- 염색
- BOF
- 발표
- 펌
- 블루블랙
- 창의공학설계
- 베이스
- 컴파일러
- 버퍼오버플로우
- 탈색
- 디버깅
- 공간복잡도
- C언어
- Calling Convention
- 피보나치
- Visual Studio
- 호출규약
- 시간복잡도
- Debug
- 동대구
- 파이썬
- 오지총
- 알고리즘
- 소켓
- 추상데이터타입
- Packet
- Today
- Total
c0smicb0y
[알고리즘] Dynamic Programming (동적 계획법) 본문
동적 계획법
정의 : 어떤 문제가 반복적이고 최적 하위구조로 이루어질때, 하위구조에 있는 부분 문제의 답을 기반으로 전체 문제의 답을 구하는 방법
최적 하위구조(Optimal Substructure)란 전체 문제의 답이 부분 문제의 답으로부터 만들어지는 구조를 말한다. 예를 들어 어떤 문제를 7개의 하위문제로 나눌 수 있을때, 7개의 하위문제의 답을 모두 얻어야 이 문제의 답을 구할 수 있다면 이 문제는 최적 하위구조를 갖추었다고 할 수 있다.
분할정복과 비슷해 보이지만, 분할정복은 문제를 큰부분에서 작은부분으로 나누는데반해(Top-Down), 동적 계획법은 제일 작은 부분부터 큰 문제로 풀어 올라간다(Bottom-Up). 또한 분할정복은 나눈 문제들을 완전히 새로운 하나의 독립된 새로운 문제로 보지만, 동적 계획법은 이전 단계의 답에 의존적이다. 그래서 한번 푼 적 있는 문제는 다시 푸는 일이 없도록 테이블 등에 저장해둔다.
알고리즘
1. 문제를 부분 문제로 나눈다.
2. 가장 작은 부분의 문제부터 답을 구한 뒤 테이블에 저장한다.
3. 테이블에 저장되어 있는 부분 문제의 답을 이용하여 점차적으로 상위 부분의 문제의 답을 구한다.
동적 계획법의 활용
1. 피보나치 수열 (Fibonacci Sequence)
피보나치 수열은 다음과 같이 정의할 수 있다.
이것을 그냥 코드로 옮기면 다음과 같이 작성된다.
int Fibonacci(int n) {
if (n > 1)
return Fibonacci(n - 1) + Fibonacci(n - 2);
else if (n == 1)
return 1;
else
return 0;
}
이 알고리즘의 수행시간은 으로 상당히 비효율적이다.
동적 계획법을 이용하여 이 알고리즘을 재구성해보자.
먼저 문제를 부분 문제로 나눈다.
은 과 의 합이다.
은 와 의 합이다.
그리고 은 과 의 합이다.
이로부터
이라는 문제를
, , …, , , 의 하위구조로 나눌 수 있는 것을 알 수 있다.
두번째로 작은 부분의 답을 구한뒤 테이블에 저장한다.
인덱스 |
저장된 값 |
0 |
0 |
1 |
1 |
2 |
1 |
3 |
2 |
4 |
3 |
5 |
5 |
6 |
8 |
... |
... |
n-2 |
|
n-1 |
|
n |
과 는 이미 정의되어 있는 값을 저장하면 되고,
부터는 테이블에 저장된 값을 이용하여 답을 구해 나간다.
계속 구해나가면 의 값을 구할 수 있다.
이렇게 구한 피보나치 수의 시간 복잡도는
이다.
분할정복으로 구한 시간 복잡도는
이였지만
동적 계획법으로 구한 시간 복잡도는
로써 분할정복보단 떨어진다.
더 나은 기법을 알기 위해서가 아니라 알고리즘 설계 기법의 이해를 위한 것이므로 뭐가 더 우수한지는 논외로 하기로 한다.
'프로그래밍 > 알고리즘' 카테고리의 다른 글
[알고리즘] Backtracking (백트래킹) (3) | 2015.01.21 |
---|---|
[알고리즘] Greedy Algorithm (탐욕 알고리즘) (5) | 2015.01.19 |
[알고리즘] Divide and Conquer (분할정복) (1) | 2015.01.11 |