2579

백준 2579번

Link: 2579번: 계단 오르기


문제 설명

오늘도 DP문제다.

그리고 오늘도 내힘으로 푸는데 실패.

앞선 두문제와 비슷하면서도 달랐는데, 이번 문제를 풀수 있느냐 없느냐는 문제를 보고 조건을 이해하여 점화식을 세울 수 있는지였다.

물론 나는 점화식 못세워서 예전 코드 보고, 검색해서 그제서야 이해해서 풀었다.

점화식 세우는 방법은 우선 DP배열의 3번째까지 채우는 방법과 동일했다.

그전에 이 문제에서 DP 배열의 의미를 이해할 필요가 있었다.

DP[N]이란 N번째 계단을 밟았음을 의미한다.

이렇게 이해하고 시작해보면 DP[1]은 첫번째 계단을 밟은것이므로 score[1]이 된다.

DP[2]는 첫번째 계단, 두번째 계단을 둘 다 밟았을때와 두번째 계단만 밟았을때의 점수를 비교하여 큰 값이 곧 DP[2]의 값이 된다.

DP[3]은 조건에 의해 세 계단을 연속으로 밟을 수 없고, 한번에 최대 2개의 계단만 오를 수 있으므로 첫번째 계단과 세번째 계단을 밟았을 때, 두번째 계단과 세번째 계단을 밟았을때의 점수를 비교하여 큰 값이 DP[3]이 된다.

DP[4]를 생각해보자. DP[4]는 첫번째 계단, 세번째 계단, 네번째 계단의 점수를 더한 값과 첫번째 계단, 두번째 계단, 네번째 계단의 점수를 더한 값을 비교하여 더 큰 값이 DP[4]이다.

이는 곧 DP[1] + score[3] + score[4], DP[2] + score[4]를 비교하는 것과 같다.

이를 토대로 점화식을 세워 보면, DP[N] = max(DP[N-3] + score[N-1] + score[N], DP[N-2] + score[N])이라는 점화식을 얻을 수 있다.

이 점화식대로 풀면 풀리는 문제다.

항상 느끼는건데 점화식 세우는게 정말 너무 어렵다. 규칙은 나름대로 찾은것 같지만 뭔가 나사 하나씩은 꼭 빠져있다는 생각이 든다.

푸는방법 까먹을때쯤 한번 더 풀어봐야 할 문제인것 같다.


정답 코드

//
// Created by Keith_Lee on 04/01/2019.
//

#include <iostream>

using namespace std;

int N;

int max(int a, int b){
    return (a > b) ? a : b;
}

int main(){
    cin >> N;

    int DP[N+1];
    int score[N+1];

    for(int i=1; i<=N; i++){
        cin >> score[i];
    }

    DP[1] = score[1];
    DP[2] = max(score[1] + score[2], score[2]);
    DP[3] = max(score[1] + score[3], score[2] + score[3]);

    for(int i=4; i<=N; i++){
        DP[i] = max(DP[i-2] + score[i], DP[i-3] + score[i] + score[i-1]);
    }

    cout << DP[N] << '\n';

    return 0;
}

Tags:

Categories:

Updated: