백준 2579 : 계단 오르기

전준형·2021년 2월 18일
0

백준

목록 보기
6/27

문제

계단 오르기 게임은 계단 아래 시작점부터 계단 꼭대기에 위치한 도착점까지 가는 게임이다. 각각의 계단에는 일정한 점수가 쓰여 있는데 계단을 밟으면 그 계단에 쓰여 있는 점수를 얻게 된다.
계단 오르는 데는 다음과 같은 규칙이 있다.

  1. 계단은 한 번에 한 계단씩 또는 두 계단씩 오를 수 있다. 즉, 한 계단을 밟으면서 이어서 다음 계단이나, 다음 다음 계단으로 오를 수 있다.
  2. 연속된 세 개의 계단을 모두 밟아서는 안 된다. 단, 시작점은 계단에 포함되지 않는다.
  3. 마지막 도착 계단은 반드시 밟아야 한다.

각 계단에 쓰여 있는 점수가 주어질 때 이 게임에서 얻을 수 있는 총 점수의 최댓값을 구하는 프로그램을 작성하시오.

입력
입력의 첫째 줄에 계단의 개수가 주어진다.

둘째 줄부터 한 줄에 하나씩 제일 아래에 놓인 계단부터 순서대로 각 계단에 쓰여 있는 점수가 주어진다. 계단의 개수는 300이하의 자연수이고, 계단에 쓰여 있는 점수는 10,000이하의 자연수이다.

출력
첫째 줄에 계단 오르기 게임에서 얻을 수 있는 총 점수의 최댓값을 출력한다.
BOJ2579

접근

알고리즘 분류는 DP 문제였지만, 반복문으로 풀 수 있을것같아 이쪽으로 먼저 접근했다. 마지막 계단을 꼭 밟아야 한다는 조건이 있으므로, 마지막 계단부터 시작해서 자신의 전 칸과 전전칸을 비교하여 더 큰 계단으로 내려가는 식으로 코드를 작성했는데, 이런 식으로 생각하면 무조건적인 최대값이 나오지 않는게 확인됐다. (세 칸 규칙이 있으므로, 때로는 작은 칸으로 이동하여 2칸 이동하는게 더 클 때도 존재한다.)

다시 돌아와 DP 문제로 해결하기 위해 점화식을 생각했다. 계단의 N번째 칸에 도착하는 방법은, N-2에서 두 칸 이동하거나, N-1에서 한 칸 이동하는 방법이지만, N-1에 도착할 때 N-2에서 한 칸 이동했다면 N-1에서 또 다시 한 칸 이동할 순 없다. 따라서 N-1에서 한 칸 이동할 경우엔 N-3에서 두 칸 이동하여 N-1로 도착하는 경우밖에 없다.

DP[N]을 N계단 까지 최대값이라고 생각한다면, DP[N-2] + N계단의 값과 DP[N-3] + N-1계단의 값 + N계단의 값 중 더 큰값이라고 볼 수 있다.

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	static int [] stair = new int[301];
	static int [] dp = new int[301];

	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(bf.readLine());

		for(int i = 1; i <= n; i++)
			stair[i] = Integer.parseInt(bf.readLine());
		
		dp[0] = 0;
		dp[1] = stair[1];
		dp[2] = stair[1] + stair[2];
		dp[3] = Math.max(stair[1] + stair[3], stair[2] + stair[3]);
		for(int i = 4; i <= n; i++) {
			dp[i] = Math.max(stair[i] + dp[i-2], stair[i] + stair[i-1] + dp[i-3]);
		}
		System.out.println(dp[n]);
	}
}
profile
한방에 맞게 해주세요

0개의 댓글

관련 채용 정보