Backjoon Online Judge 

"2579번 : 계단 오르기" 문제입니다.


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


문제에서 선택된 수의 최대값을 구하기 위해 DP를 이용하였습니다.

규칙 파악을 하기위해 k번째 계단을 올랐을때 최댓값을 구했습니다.


(k번째 계단의 점수를 s(k), k번째 계단의 점수의 합을 ms(k)로 표시합니다.)

1번째 계단까지 올라갔을 때 최댓값 : s(1)

2번째 계단까지 올라갔을 때 최댓값 : s(1)+s(2)

3번째 계단까지 올라갔을 때 최댓값 : max( [ s(1)+s(2) ] , [ s(2)+s(3) ] )

(1,2,3번째 계단을 모두 오를 수 없으므로)


이때 3번째 계단에 오르게 되는 경우의 수는

1. 이전 계단을 밟고 올라옴. [s(2)를 포함]

2. 이전 계단을 밟지 않고 올라옴. [s(2)를 포함하지 않음] 으로 나뉩니다.


1의 경우 이전 계단과 현재 계단을 밟으므로 2칸 아래 계단을 밟을 수 없고 3칸 아래 계단에서 최대 점수를 얻었을때 최대 점수를 얻을 수 있습니다.

2의 경우 이전 계단을 밟지 않았으므로 그 이전 계단까지 최대 점수를 얻으면 k번째 계단에서 최대 점수를 얻을 수 있습니다.


이를 일반화 해서 표현하면

k번째 계단까지 올라갔을 때 최댓값은

max( [ ms(n-3) + s(n-1) + s(n) ] , [ ms[n-2] + s(n) ] ) 이 됩니다.


아래는 코드 설명입니다.

 - 각 계단의 점수와 각 계단 위치에서 최댓값을 저장하기 위해 각각 score[Max]와 maxScore[Max] 배열을 선언했습니다.

 - 이후 maxScore[2]까지는 초기값으로 직접 값을 넣어주고 maxScore[3]부터는 위의 공식을 통해 계산하였습니다. 


코드는 C++로 작성하였습니다.

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
#include <iostream>
#include <algorithm>
#include <memory.h>
 
#define MAX 301
 
using namespace std;
 
int main() {
    int stair;
    int score[MAX];
    int maxScore[MAX];
 
    cin >> stair;
    score[0= 0;    // 시작지점
    for(int i = 1; i <= stair; i++) {
        cin >> score[i];
    }
 
    maxScore[0= 0;    // 시작 지점
    maxScore[1= score[1];
    maxScore[2= score[1+ score[2];
    //maxScore[3] = max(score[1] + score[3], score[2] + score[3]);
 
    for (int i = 3; i <= stair; i++) {
        maxScore[i] = max(maxScore[i - 2], maxScore[i - 3+ score[i - 1]) + score[i];
    }
    cout << maxScore[stair] << endl;
}
 
 

cs


'Programming 문제풀이 > Backjoon Online Judge' 카테고리의 다른 글

1005번 : ACM Craft  (0) 2018.05.12
1463번 : 1로 만들기  (0) 2018.05.10
1932번 : 숫자삼각형  (0) 2018.05.01
1149번 : RGB거리  (0) 2018.04.01
1003번 : 피보나치 함수  (0) 2018.04.01