문제링크 : https://www.acmicpc.net/problem/2579

 

2579번: 계단 오르기

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

www.acmicpc.net

필자는 이 문제의 출처가 정보올림피아드 '초등부'라는 걸 알았는데 꽤나 충격을 받았다... 난 초등학교 때 뭐했지...ㅠㅠ 각설하고, 설명을 해보도록 하겠다.

 

이 문제는 메모이제이션을 통한 다이나믹 프로그래밍 문제이다. 그렇다면 대체 무엇을 메모리에 남겨야할까?! 바로 각 계단까지 올라왔을 때의 점수의 최댓값이다. 코드는 아래와 같다.

 

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
 
public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        int[] scores = new int[300];
        int[] max = new int[300];
        
        for(int i = 0; i < n; i++) {
            scores[i] = Integer.parseInt(br.readLine());
        }
        
        max[0= scores[0];
        max[1= scores[0+ scores[1];
        max[2= Math.max(scores[0], scores[1]) + scores[2];
        
        for(int i = 3; i < n; i++) {
            max[i] = Math.max(max[i - 2], max[i - 3+ scores[i - 1]) + scores[i];
        }
        
        System.out.println(max[n - 1]);
    }
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

0, 1, 2 번째 계단까지 올라갔을 때 얻을 수 있는 최댓값에 대한 식은 다들 무리없이 이해할 수 있으리라고 본다. 그 다음 로직에 대해서 설명을 하면, i번째 계단에 오르기 위해선 i - 1번째 계단이나 i - 2번째 계단 둘 중 하나에서 올라와야한다. 두 가지 경우 중, 큰 값을 가지는 경우를 max값에 넣으면 된다. 근데 i - 1번째에서 올라올 경우, max[i - 1]의 값이 바로 i - 2번째 계단을 선택한 값인지 아닌지를 알 수가 없다. (i - 2번째 계단을 선택한 최댓값일 경우, i를 선택할 수 없으므로) 헌데 i번째, i - 1번째 계단 둘을 선택할 경우, i - 2번째 계단을 선택할 수는 없으므로 i - 3번째에서 왔을 것이다. 따라서 i - 1번째 계단에서 올라왔을 경우는 i - 1번째 계단의 점수와 i - 3번째 점수의 최댓값을 더하면 된다.

조금 다른 방식으로 풀 수도 있다. max를 2차원 배열로 선언하여, 바로 다음 계단을 선택할 수 있을 경우의 최댓값과 없는 경우의 최댓값을 저장하는 것이다. 코드는 아래와 같다.

 

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
 
public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        int[] scores = new int[300];
        int[][] max = new int[2][300];
        
        for(int i = 0; i < n; i++) {
            scores[i] = Integer.parseInt(br.readLine());
        }
        
        max[0][0= scores[0];
        max[0][1= scores[1];
        max[1][1= scores[0+ scores[1];
        
        for(int i = 2; i < n; i++) {
            max[0][i] = Math.max(max[0][i - 2], max[1][i - 2]) + scores[i];
            max[1][i] = max[0][i - 1+ scores[i];
        }
        
        System.out.println(Math.max(max[0][n - 1], max[1][n - 1]));
    }
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

+ Recent posts