백준-2579. 계단 오르기

2579 2579

  • 2차원 다이나믹으로 풀이 a[n] : n번째 계단의 값.
    d[n][t] : n번째 계단을 연속으로 t번째 밟은 경우의 최댓값.
    이경우 여기선 연속으로 1번이나 2번 밟을 수 밖에없으므로, t는 1또는 2.
    따라서, 우리가 구해야하는 d[n]은 d[n][1] 또는 d[n][2]중 더 큰 값이 되는것이다.

2579

d[n][1] = max(d[n-2][1], d[n-1][2]) + a[n]

2579

d[n][2] = d[n-1][1] + a[n]

따라서, 구하고자하는 점화식은 d[n] = max(d[n][1] , d[n][2]) 처음 1,2,3 계단은 앞의 경우가 없으므로 간단히 입력 후 시작.

1차원은 단순히 최댓값만 저장하는 방식이고, 2차원은 가능한 경우를 모두 저장한다는 방식의 차이 뿐이다.

C++ 코드(2차원 다이나믹/bottom-top)

#include <iostream>
using namespace std;

int d[301][3], a[301];

int main() {
	int n;
	cin >> n;

	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	d[0][1] = a[0];
	d[1][1] = a[1];
	d[1][2] = a[0] + a[1];

	for (int i = 2; i < n; i++) {
		d[i][1] = max(d[i - 2][1], d[i - 2][2]) + a[i];
		d[i][2] = d[i - 1][1] + a[i];
	}
	cout << max(d[n - 1][1], d[n - 1][2]);

}

C++ 코드(1차원 다이나믹/bottom-top)

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

long arr[100] = { 0,1 };

int main() {

	int n = 0;
	scanf("%d", &n);
	for (int i = 2; i <= n; i++) arr[i] = arr[i - 1] + arr[i - 2];
	printf("%lld", arr[n]);
}

C++ 코드(top-bottom)

#include <iostream>
using namespace std;

int d[301], a[301];

int dp(int n) {
	//base check
	if (n == 0) return a[0];
	else if (n == 1) return a[0] + a[1];
	else if (n == 2) return max(a[0] + a[2], a[1] + a[2]);

	//memoization
	if (d[n] > 0) return d[n];

	//recurence relation
	int v = dp(n - 2) + a[n];
	int k = dp(n - 3) + a[n - 1] + a[n];
	d[n] = max(v, k);

	return d[n];
}

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

	int n; 
	cin >> n;
	for (int i = 0; i < n; i++) cin >> a[i];

	cout << dp(n - 1);
}

C# 코드

using System.Text;
using System;
using static System.Console;

class Program
{
    static int[] stairs = new int[302];
    static int[] sum = new int[302];
    public static void Main(string[] args)
    {
        int n = int.Parse(ReadLine());
        for(int i =1; i <= n; i++)
        {
            stairs[i] = int.Parse(ReadLine());
        }

        sum[1] = stairs[1];
        sum[2] = stairs[1] + stairs[2];
        sum[3] = Math.Max(stairs[1], stairs[2]) + stairs[3];

        for(int i = 4; i <= n; i++)
        {
            sum[i] = Math.Max(sum[i - 3] + stairs[i - 1], sum[i - 2]) + stairs[i];
        }
        Write(sum[n]);
    }
}

Java 코드

import java.util.*;

public class Main {
    static long[] stairs = new long[302];
    static long[] sum = new long[302];

    public static void main(String[] args) {

        Scanner s = new Scanner(System.in);
        int n = s.nextInt();
        for(int i = 1; i <= n; i++){
            stairs[i] = s.nextInt();
        }
        sum[1] = stairs[1];
        sum[2] = stairs[1] + stairs[2];
        sum[3] = Math.max(stairs[1], stairs[2]) + stairs[3];
        for(int i = 4; i<=n; i++){
            sum[i] = Math.max(sum[i-3] + stairs[i-1], sum[i-2]) + stairs[i];
        }

        System.out.println(sum[n]);

    }

}

Kotlin 코드

import java.util.*
import kotlin.math.*

fun main(args: Array<String>){
    val stairs = IntArray(302)
    val sum = IntArray(302)
    val s = Scanner(System.`in`)
    val n = s.nextInt()
    for(i in 1..n){
        stairs[i] = s.nextInt()
    }

    sum[1] = stairs[1]
    sum[2] = stairs[1] + stairs[2]
    sum[3] = Math.max(stairs[1], stairs[2])+ stairs[3]
    for(i in 4..n){
        sum[i] = Math.max(sum[i-3]+stairs[i-1], sum[i-2])+stairs[i]
    }

    print(sum[n])
}

Python 코드

stairs = [0 for _ in range(302)]
sum = [0 for _ in range(302)]

n = int(input())
for i in range(1, n+1):
    stairs[i] = int(input())
sum[1] = stairs[1]
sum[2] = stairs[1] + stairs[2]
sum[3] = max(stairs[1], stairs[2]) + stairs[3]
for i in range(4, n+1):
    sum[i] = max(sum[i-3] + stairs[i-1], sum[i-2]) + stairs[i]

print(sum[n])

© 2021. All rights reserved.

----------Heesoo's Tech History----------

by C.H.S