Algorithm/BOJ

BOJ] 2579. 계단오르기

BOJ]2579.계단오르기

https://www.acmicpc.net/problem/2579

 

2579번: 계단 오르기

계단 오르기 게임은 계단 아래 시작점부터 계단 꼭대기에 위치한 도착점까지 가는 게임이다. <그림 1>과 같이 각각의 계단에는 일정한 점수가 쓰여 있는데 계단을 밟으면 그 계단에 쓰여 있는 점수를 얻게 된다. 예를 들어 <그림 2>와 같이 시작점에서부터 첫 번째, 두 번째, 네 번째, 여섯 번째 계단을 밟아 도착점에 도달하면 총 점수는 10 + 20 + 25 + 20 = 75점이 된다. 계단 오르는 데는 다음과 같은 규칙이 있다. 계단은 한 번에 한 계단씩

www.acmicpc.net

DP는 고민하고 또 고민해야한다. 점화식(규칙)을 찾아야한다!

문제에서의 아래 규칙을 고려하여 점화식을 구해야한다.

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

규칙을 봤을 때, k번째 계단을 갈수 있는지 없는지 고려하는 방법을 생각해야했다.
그래서 2차원배열의 2번째 col의 index에 규칙을 주었다.
index 0은 한번 더 밟을 수 있는 값을 넣기.
index 1은 이미 연속해서 두번째 밟은 값을 넣기.


즉, memo[k][0]이 의미하는 것은 k번째 계단까지 얻은 최댓값인데, 처음 밟은 계단이므로, k+1번째에서 이 값을 활용할 수 있다.
memo[k][1]이 의미하는 것은 역시 k번째 계단까지 얻은 최댓값인데, 이미 두번연속 밟았으므로 k+1번째에서 이 값을 쓸 수 없다.
라는 것이다.

k+1번째를 생각해보자.
memo[k+1][1]은 memo[k][0]의 값과arr[k+1]의 값을 더한 값이 된다. (연속으로 밟았을 때의 값)
다음, memo[k+1][0]은 처음 밟은 값을 저장해야 하는데, 바로 이전 값(k)번째 값은 참고할 수 없다.


그러므로, 2번째 전 계단의 값을 참고해야 하는데, 이 떄는 2번째 전 계단의 값 중 최댓값을 가져오면 된다.
즉, memo[k+1][0]은 memo[k-1][0] 과 memo[k-1][1]중 큰 값이 들어가게 되는 것이다.


위 규칙을 고려하여 index 0과 1을 나눠서 흐름을 따라가보면 이해가 될 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class bj_2579_계단오르기 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int[] arr = new int[N];
        int[][] memo = new int[N][2];
        
        for(int i=0; i<N; i++)
            arr[i] = sc.nextInt();
        
        // 2번째 col의 의미
        // 0:한번더밟을수있음
        // 1:연속해서못밟음(이미 두번연속 밟음)
        memo[0][0]=arr[0];
        if(N!=1) {
            memo[1][0]=arr[1];
            memo[1][1]=arr[0]+arr[1];
        }
        for(int i=2; i<N; i++) {
            for(int j=0; j<2; j++) {
                if(j==0) {
                    memo[i][j] = Math.max(memo[i-2][0], memo[i-2][1]) + arr[i];
                }
                else {
                    memo[i][j] = memo[i-1][0+ arr[i];
                }
            }
        }
        System.out.println(Math.max(memo[N-1][0], memo[N-1][1]));
    }
}
 
cs

'Algorithm > BOJ' 카테고리의 다른 글

BOJ] 14502. 연구소  (0) 2020.01.28
BOJ] 2805. 나무 자르기  (0) 2019.10.05
BOJ] 4179. 불!  (0) 2019.10.05
BOJ] 16283. Farm  (0) 2019.10.01
BOJ] 1003. 피보나치 함수  (0) 2019.09.24