Algorithm

[백준] 계단오르기 2579번 (c++)

salmon16 2022. 7. 21. 10:27

풀이 방법

반복된 계산을 줄여 풀이하는 dp 문제이다

stairs배열에는 계단의 점수를 저장하였다. (0인덱스에는 시작점)

dp배열은 dp[i] ==  i번째 계단까지 오는 최대 점수이다 (i 계단을 밞고 있어야 한다)

dp[1]은 당연히 stairs[1]이고 dp[2]는 stairs[1] + stairs[2]보다 큰 경우는 없으므로 stairs[1] + stairs[2]가 된다.

그럼 dp[3]은 stairs[1] + stairs[3] 또는 stairs[2] + stairs[3]가 될 수 있다.

그럼 dp[n]인 경우 점화식은 dp[n-3] + stairs[n-1] + stairs[n] (n-3을 밞고 있는 경우 중 최대 + n-2계단 뛰어넘고 n-1, n-2 계단 연속으로 밞기) 또는 dp[n-2] + stairs[n] (n-2 계단 밞는 경우 중 최대 + n-1 뛰어넘고 n밞기) 둘 중 하나가 된다.

bottom up 방식

#include <bits/stdc++.h>
using namespace std;

int n;
int dp[301];
int stairs[301];



int main() {
    cin >> n;
    memset(dp, 0, sizeof(dp));
    for (int i = 1;i < n + 1;i++) { // i == 0 일때는 시작점
        cin >> stairs[i];
    }
    dp[1] = stairs[1];
    dp[2] = stairs[1] + stairs[2];
    for (int i = 3;i <= n;i++) {
        dp[i] = max(dp[i - 2] + stairs[i], dp[i-3] + stairs[i-1] + stairs[i]);
    }
    cout << dp[n];
    return 0;
}

top down 방식

#include <bits/stdc++.h>
using namespace std;

int n;
int dp[301];
int stairs[301];


int solve(int x) {
    if (dp[x] == -1)
        dp[x] = max(solve(x - 2) + stairs[x],solve(x - 3) + stairs[x - 1] + stairs[x] );
    return dp[x];
}

int main() {
    cin >> n;
    memset(dp, -1, sizeof(dp));
    for (int i = 1;i < n + 1;i++) { // i == 0 일때는 시작점
        cin >> stairs[i];
    }
    dp[0] = 0;
    dp[1] = stairs[1];
    dp[2] = stairs[1] + stairs[2];
    solve(n);
    cout << dp[n];
    return 0;
}

'Algorithm' 카테고리의 다른 글

[백준] 그림 1926번 (c++)  (0) 2022.08.23
[백준] 동전1 2293번 (c++)  (0) 2022.08.02
[백준] N-Queen 9663번 (c++)  (0) 2022.07.15
[백준] 플로이드 11404번 (c++)  (0) 2022.07.11
[백준] 다리 만들기 2146번 (c++)  (0) 2022.07.07