Official

C - 階段の上り方 / Ways to Climb Stairs Editorial by admin

DeepSeek V3

Overview

This is a dynamic programming problem where you need to find the total number of ways to climb stairs, moving 1, 2, or 3 steps at a time, while avoiding broken steps.

Analysis

This problem is a stair-climbing problem with the constraint of “not stepping on broken steps.” The key observations are as follows:

  1. The number of ways to reach each step i can be computed as the sum of moves from 1 step before (i-1), 2 steps before (i-2), and 3 steps before (i-3)
  2. Since broken steps cannot be reached, the number of ways for those steps is 0
  3. It is possible to jump over broken steps (there is no problem as long as you don’t land on them)
  4. Since N can be as large as \(10^5\), an efficient algorithm is needed

A naive recursive approach results in exponential time complexity, which is far too slow for \(N=10^5\). By using dynamic programming, we can achieve an efficient solution that computes the number of ways for each step only once.

Algorithm

Using dynamic programming, we compute dp[i] as the total number of ways to reach step i:

  1. dp[0] = 1 (initial state: standing on the ground)
  2. For each step i (1 ≤ i ≤ N):
    • If i is a broken step, then dp[i] = 0
    • Otherwise: dp[i] = dp[i-1] + dp[i-2] + dpi-3
  3. The final answer is dp[N]

Note that we must be careful not to add terms where i-1, i-2, or i-3 are out of bounds.

Complexity

  • Time complexity: \(O(N)\)
  • Space complexity: \(O(N)\)

Implementation Notes

  1. Store the set of broken steps in a set for fast existence checks

  2. Don’t forget to apply MOD operations (since the answer can become extremely large)

  3. Be careful with array index ranges (from step 0 to step N)

  4. Be careful with input handling when M=0 (the second line may not exist)

    Source Code

MOD = 10**9 + 7

def main():
    import sys
    data = sys.stdin.read().split()
    if not data:
        print(0)
        return
        
    n = int(data[0])
    m = int(data[1])
    broken = set()
    if m > 0:
        for i in range(2, 2 + m):
            broken.add(int(data[i]))
            
    dp = [0] * (n + 1)
    dp[0] = 1
    
    for i in range(1, n + 1):
        if i in broken:
            dp[i] = 0
            continue
        if i - 1 >= 0:
            dp[i] = (dp[i] + dp[i - 1]) % MOD
        if i - 2 >= 0:
            dp[i] = (dp[i] + dp[i - 2]) % MOD
        if i - 3 >= 0:
            dp[i] = (dp[i] + dp[i - 3]) % MOD
            
    print(dp[n] % MOD)

if __name__ == "__main__":
    main()

This editorial was generated by deepseekv3.

posted:
last update: