BOJ

[백준] 2579번 계단 오르기 - C++

DP, 다이나믹 프로그래밍

Posted by dongjune on December 17, 2020

문제

2579번 계단 오르기

풀이

문제의 포인트는

  • 계단을 1칸씩 또는 한 칸 뛰어서 오를 수 있다.
  • 계단을 3칸 연속으로 오르면 안된다.
  • 계단마다 점수가 있다.
  • 마지막 계단에 반드시 도착해야 한다.
  • 마지막 계단에 도착할 때까지 지나올 수 있는 계단의 최대 값을 구한다.

반복문과 재귀함수 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
27
28
29
30
31
32
#include <algorithm>
#include <vector>
#include <iostream>

using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int n;
    cin >> n;
    vector<int> steps(n + 1);
    vector<vector<int>> cache(n + 1, vector<int>(2, 0));
    for (int i = 1; i < n + 1; i++)
        cin >> steps[i];

    cache[1][0] = cache[1][1] = steps[1];
    for (int i = 2; i < n + 1; i++)
    {
        // 두칸 점프해서 현재 계단 i로 온 경우
        cache[i][0] = max(cache[i - 2][0], cache[i - 2][1]) + steps[i];
        // 한칸 점프해서 현재 계단 i로 온 경우
        // 이 경우에는 바로 전 칸의 두 칸 점프한 경우만 가능
        cache[i][1] = cache[i - 1][0] + steps[i];
    }
    int res = max(cache[n][0], cache[n][1]);
    cout << res;
    return 0;
}

재귀함수 사용

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
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

int steps[301];
int cache[301][2];
int n;

int getMaxScore(int L, int isContinuos)
{
    int &ret = cache[L][isContinuos];

    // 기저 사례
    if (L < 0)
        return 0;
    if (L == 0)
        return steps[0];
    // 이미 구했으면 바로 return
    if (ret != -1)
        return ret;

    // 현재 계단이 2개 붙어있는 경우
    // 전 칸의 계단은 검사하지 않는다.
    if (isContinuos == 1)
        return cache[L][isContinuos] = steps[L] + getMaxScore(L - 2, 0);
    // 현재 계단이 다른 계단과 붙어있지 않은 경우
    // 바로 전의 계단과 2칸 전의 계단을 모두 검사
    else
        return cache[L][isContinuos] = steps[L] + max(getMaxScore(L - 1, 1), getMaxScore(L - 2, 0));
}

int main()
{
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> steps[i];
    memset(cache, -1, sizeof(cache));
    cout << getMaxScore(n - 1, 0);

    return 0;
}