DP(Dynamic Programming)는 암기 과목이 아니라 '문제를 쪼개서 생각하는 사고법'에 가깝습니다. 특정 유형을 외우기보다, 어떤 문제든 DP로 풀 수 있게 만드는 '생각의 틀'을 잡는 것이 중요합니다.
DP를 효과적으로 공부하기 위한 체계적인 접근법입니다.
DP의 두 가지 대표적인 방식, 메모이제이션(Memoization)과 타뷸레이션(Tabulation)의 차이를 이해하는 것부터 시작해라.
처음에는 어떤 방식이든 하나만 정해서 익숙해지는 것을 추천합니다. 대부분의 코딩 테스트에서는 Bottom-up 방식이 주로 사용됩니다.
새로운 DP 문제를 만났을 때, 항상 아래 3가지 질문을 스스로에게 던지는 연습을 하세요.
DP 상태 정의 (dp[i]는 무엇인가?): dp 배열의 각 칸이 어떤 의미를 갖는지 명확하게 정의해야 합니다.
dp[i] = i원을 만드는 동전의 최소 개수)dp[i] = i번째 집까지 칠하는 최소 비용)점화식 찾기 (dp[i]와 이전 값들의 관계는?): i번째 문제의 정답(dp[i])을 그보다 작은 문제들의 정답(dp[i-1], dp[i-2] 등)을 이용해 어떻게 구할 수 있을지 고민합니다. 여기가 DP의 핵심입니다.
dp[i]는 dp[i-1]과 dp[i-2]를 더한 값이다.)dp[i]는 dp[i-1], dp[i-2], dp[i-5] 중 최솟값에 1을 더한 값이다.)초기값 설정 (Base Case는 무엇인가?): 점화식이 시작될 수 있는 가장 작은 문제의 정답(dp[0], dp[1] 등)을 직접 계산해서 dp 배열에 넣어줍니다. 이 기반이 없으면 점화식이 무너집니다.
무작위로 풀기보다, 클래식한 유형별로 묶어서 풀며 패턴을 익히는 것이 효과적입니다.
문제를 푼 후에 다른 사람들은 어떻게 풀었는지 꼭 확인해라. 같은 문제라도 점화식을 다르게 세우거나, DP 상태를 더 효율적으로 정의하는 방법을 배울 수 있습니다.
아래 문제들을 순서대로 풀어보시면 DP에 대한 감을 잡는 데 큰 도움이 될 겁니다.
dp[i]를 정의하고, i-1, i-2, i-3과의 관계를 찾는 연습을 하기에 좋습니다.dp 배열을 2차원으로 확장(dp[i][색깔])하는 첫걸음입니다.