-

[BOJ - JAVA] 2579 - 계단 오르기(DP, 점화식) 본문

백준 문제 풀이

[BOJ - JAVA] 2579 - 계단 오르기(DP, 점화식)

흣차 2021. 10. 20. 01:14
728x90
반응형

# 주소

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에 담아 출력하시면 되겠습니다.

728x90
반응형
Comments