階段を登る

8743 ワード

https://www.acmicpc.net/problem/2579
各階段に点数があり、最大点数を獲得して先端に達するゲーム.到着した階段は必ず踏まなければなりません.
一度に1間か2間歩くことができ、連続して3間歩くことはできません.
これは、ステップ分数配列を入力して最大分数を出力する必要があるという問題です.
DPで解決できます.
dp[n]はn格子までの最大スコアである(n格子到達ステップ)(ステップ分数配列a[n])
nを踏むと、以前の状況を2つに分けることができます.
  • n前の1段(n-1)の
  • を直接踏む
  • 前の段を踏まなければ
  • となる.
    1の場合、n-2を踏んだ場合、連続3マスなので、n-2を踏んではいけません.
    2の場合、無条件にn-2を踏む.3コマは走れないから.

    これを点火式として表します.以下に示します.
    1. dp[n] = ( dp[n-3] + a[n-1] ) + a[n]
    // dp[n-1]이 아닌 a[n-1] 이유는 dp[n-1]는 n-2를 밟았는지 여부를 알 수 없기 때문
    2. dp[n] = dp[n-2] + a[n]
    import java.util.Scanner;
    
    public class Main
    {
        public static void main(String[] args)
        {
            Scanner sc = new Scanner(System.in);
            
            int n = sc.nextInt(); // 계단 수
            
            int[] dp = new int[n+1]; // 누적 값 저장 배열
            int[] arr = new int[n+1]; // 계단 점수 배열
            
            // 이해 쉽게 인덱스 1부터 시작
            for (int i=1; i<=n; i++)
                arr[i] = sc.nextInt();
                
            dp[0] = 0; // 시작
            dp[1] = arr[1]; // 계단 하나일 때
            
            if (n >= 2) // n=1인 경우 대비
                dp[2] = arr[1] + arr[2];
                
            for(int i=3; i<=n; i++)
            {
                dp[i] = Math.max(dp[i-2], dp[i-3] + arr[i-1]) + arr[i];
            }
            
            System.out.println(dp[n]);
        }
    }