- 복잡한 문제를 간단한 여러 개의 문제로 나누어 푸는 방법
- 문제를 여러 개의 하위 문제로 나누어 각 하위 문제를 계산하고 계산한 값을 저장, 후에 같은 하위 문제가 나왔을 경우 저장된 값을 사용하여 간단하게 해결
- 부분 문제 반복과 최적 부분 구조를 가지고 있는 알고리즘을 일반적인 방법에 비해 적은 시간으로 풀고 싶을 때 사용
- 하위 문제의 수가 기하급수적으로 증가할 때 유용
※ 최적 부분 구조: 부분 문제의 최적 결과값을 사용해 전체 문제의 최적 결과를 낼 수 있는 구조
f(n)=f(n-1)+f(n-2)
)※ 대부분의 DP 문제는 Tabulation 방식이 권장
피보나치 수 2
분류: 수학, DP
n이 주어졌을 때, n번째 피보나치 수를 구하는 프로그램을 작성하시오.
def fib(n):
f = [0, 1, 1]
for i in range(3, n + 1):
f.append(f[i - 1] + f[i - 2])
return f[n]
n = int(input())
print(fib(n))
피보나치 점화식: f(n)=f(n-1)+f(n-2)
f 라는 리스트에 피보나치 값을 저장하여 재귀를 사용하지 않고 필요할 때 f 리스트에서 값을 가져와서 사용
1, 2, 3 더하기
분류: DP
정수 n이 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법의 수
def plus_cnt(n):
cnt_list = [0, 1, 2, 4]
for i in range(4, n + 1):
cnt_list.append(cnt_list[i - 1] + cnt_list[i - 2] + cnt_list[i - 3])
return cnt_list[n]
for i in range(int(input())):
n = int(input())
print(plus_cnt(n))
점화식: f(n)=f(n-1)+f(n-2)+f(n-3)
1로 만들기
분류: DP
정수 N이 주어졌을 때, 세 개의 연산을 사용하여 1을 만드는 연산의 최솟값
x = [0, 0, 1, 1]
n = int(input())
for i in range(4, n + 1):
x.append(x[i - 1] + 1)
if i % 3 == 0:
x[i] = min(x[i // 3] + 1, x[i])
if i % 2 == 0:
x[i] = min(x[i // 2] + 1, x[i])
print(x[n])
10의 경우 10,5,4,2,1 보다 10,9,3,1이 연산의 최솟값을 가진다.
x-1
의 연산값과 3, 2로 나눈 x
의 연산값들을 비교하여 연산값이 작은 것을 저장