-
[BOJ - JAVA] 2579 - 계단 오르기(DP, 점화식) 본문
# 주소
https://www.acmicpc.net/problem/2579
2579번: 계단 오르기
계단 오르기 게임은 계단 아래 시작점부터 계단 꼭대기에 위치한 도착점까지 가는 게임이다. <그림 1>과 같이 각각의 계단에는 일정한 점수가 쓰여 있는데 계단을 밟으면 그 계단에 쓰여 있는 점
www.acmicpc.net
# 문제
# 문제 해설 및 코드 리뷰
import java.util.Scanner;
public class Main {
static Integer dp[];
static int arr[];
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
dp = new Integer[1];
arr = new int[1];
for(int i = 1; i <= n; i++) {
arr[i] = in.nextInt();
}
dp[0] = arr[0]; // 디폴트값이 null이므로 0으로 초기화 해주어야한다.
dp[1] = arr[1];
if(n >= 2) {
dp[2] = arr[1] + arr[2];
}
System.out.println(find(n));
}
static int find(int n) {
if(dp[n] == null) {
dp[n] = Math.max(find(n - 2), find(n - 3) + arr[n - 1]) + arr[n];
}
return dp[n];
}
}
어제 풀었던 문제와 흡사한 메모이제이션 코딩입니다.
메모이제이션이란 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술입니다. 동적 계획법의 핵심이 되는 기술로서 DP를 푸는 사람들에겐 꼭 알아두어야 할 기술이라고 할 수 있겠습니다.
원래 dp[n]은 0일 때(방문하지 않은 dp값) dp[n]을 구하면 되겠으나 그렇게 될 경우 연산 속도가 느려지기 때문에 dp[n]이 null인(dp는 Integer로 선언했으므로 null일 때) 값에 대해서 dp의 max값을 구하면 되겠습니다.
이 문제의 정답률이 이렇게나 낮은 이유는 아마 순차적으로 n에 값을 더해서 그런 것이라 사료됩니다.
하지만 그렇게 풀이하면 안되고 n-2인덱스에서의 크기와 n-1, n-3, n의 값을 더한 값에서의 크기를 서로 비교하여 큰 값에 대해서 dp에 값을 저장해야 합니다. 그러니까, 연속적으로 세 개의 값이 들어가면 안되는 것을 잘 인지하고 계신다면 결국 들어갈 값은 1,2가 연속으로 들어간 값과 find(n-3)의 값과 find(n-2)의 값을 비교해주시면 되겠습니다.
결국 재귀함수를 제대로 이해하고 있어야 한다는 뜻인데, 여기서 arr[n]과 arr[n-1]과 더해진 find(n-3)의 값은 또다시 find(n-5)와 find(n-6) + arr(n-3) + arr(n-4)의 값 중 더 큰 값이 됩니다. 이런식으로 n이 1이 될 때 까지 값을 다 더하여 max에 담아 출력하시면 되겠습니다.
'백준 문제 풀이' 카테고리의 다른 글
[BOJ - JAVA] 10773 - 제로(스택) (0) | 2021.10.24 |
---|---|
[BOJ - JAVA] 1010 - 다리 놓기(DP, 조합) (0) | 2021.10.20 |
[BOJ - JAVA] 1912 - 연속합(DP) (0) | 2021.10.18 |
[BOJ - JAVA] 1895 - 필터(슬라이딩 윈도우) (0) | 2021.10.18 |
[BOJ - JAVA] 10870 - 피보나치 수열 5(DP) (0) | 2021.10.17 |