전체 문제를 한 번에 해결하는 것이 아니라 작은 부분 문제들을 해결하고, 이를 활용하여 전체 문제를 해결하는 방법
동적 계획법을 효율적으로 활용하려면 아래 두 가지 조건을 만족해야
큰 문제를 작은 문제로 나누었을 때 동일한 작은 문제가 반복해서 등장해야 함
-> 중복 부분 문제
큰 문제의 해결책은 작은 문제의 해결책의 합으로 구성할 수 있어야 함
-> 최적 부분 구조
동적계획법의 핵심은 단순히 작은 문제를 조합해서 큰 문제를 해결하는게 아님 !
작은 문제들이 같아야 하고 반복되어야 함
큰 문제를 작은 문제들로 나눴지만 작은 문제들이 겹치지 않으면 효율적인 거 아님 x
동적 계획법으로 문제를 해결하는 절차는 아래와 같음
** 그림을 그려서 식을 알아내 !
점화식 구현 : 재귀 활용
재귀는 재귀 함수의 반환값을 활용한다는 특징이 있음
재귀는 스택 메모리에 함수 호출 정보가 많이 쌓여 메모리 한계로 런타임 오류 생길 수 있음
문제가 생기면 쓸 수 있는 방법
1. 재귀 호출 자체를 쓰지 않는 반복문
2. 재귀 호출의 횟수를 줄이는 메모이제이션
재귀 호출의 횟수를 줄이는 메모이제이션
이미 계산한 값을 저장해두었다가 이후 쓸 일이 있을 때 활용하는 개념
** 코딩테스트에서는 배열을 활용하여 메모이제이션하기를 추천 !
부분 수열이란?
주어진 수열 중 일부를 뽑아 새로 만든 수열
( 이때 각각의 원소는 전후 관계를 잘 유지해야 함 )
부분 수열의 원소가 오름차순을 유지하면서도 길이가 가장 긴 수열을 말함
LIS의 길이 동적 계획법으로 구하기
점화식 :
부분 수열의 용어를 보고 단순히 '숫자의 나열'이라고 생각할 수 있지만
수학적인 의미로는 '특정 순서로 숫자를 나열한 것'
두 수열이 어떤 기준에 따라 양쪽에서 공통으로 발견할 수 있는 가장 긴 부분 수열을 의미
부분 수열은 원소 사이의 순서만 유지하면 되고 반드시 연속할 필요는 없음
LCS() 함수 정의
LCS(i,j)=x[1...i]와 y[1...j]의 LCS의 길이
LCS(2,3)에서 +1을 하면 LSC(3,4) <- 단 새로 더하는 값이 같을 경우에 만족
만약 새로 더하는 값이 다르다면 x[3]과 y[4]는 포함하지 않는 LCS의 길이를 찾아야 함
즉 LCS(3,3) 혹은 LCS(2,4) 중에서 선택해야
x[i]와 y[j]가 다르면 LCS(i,j)=LCS(i-1,j)와 LCS(i,j-1)을 비교하여 큰 값으로 함
즉