CMD Guide
HomeDSADynamic Programming

Staircase

The number of ways to reach step n is the sum of the ways to reach each step you could have jumped from — ways(n) = ways(n-1) + ways(n-2) + ways(n-3) — because every path to step n ends with exactly one last jump of size 1, 2, or 3, and those three cases partition all paths with no overlap.

Recognize the pattern

Brute force → optimal

Brute force: recursion directly on the recurrence, branching 3 ways at each step with no memory of repeated subproblems.

long waysBrute(int n) {
    if (n == 0) return 1;
    if (n < 0) return 0;
    return waysBrute(n-1) + waysBrute(n-2) + waysBrute(n-3);
}

Cost: exponential — same sub-value of n (e.g. waysBrute(5)) gets recomputed from scratch every time it's reached via a different jump sequence. Space: O(n) recursion stack only, but time is the killer.

Optimal: since ways(k) only ever needs to be computed once, cache it (top-down memo) or fill it bottom-up in a small array, then compress to three rolling variables. Note the return/array type is long, not int — see Pitfalls below for why.

long waysDP(int n) {
    if (n == 0) return 1;
    long[] dp = new long[n + 1];
    dp[0] = 1;
    for (int i = 1; i <= n; i++) {
        dp[i] = (i - 1 >= 0 ? dp[i-1] : 0)
              + (i - 2 >= 0 ? dp[i-2] : 0)
              + (i - 3 >= 0 ? dp[i-3] : 0);
    }
    return dp[n];
}

// O(1) space, rolling window of the last 3 values
long waysDPOptimal(int n) {
    if (n == 0) return 1;
    if (n == 1) return 1;
    if (n == 2) return 2;
    long a = 1, b = 1, c = 2; // ways(0), ways(1), ways(2)
    for (int i = 3; i <= n; i++) {
        long next = a + b + c;
        a = b; b = c; c = next;
    }
    return c;
}

Complexity, derived

Time: the array/rolling loop runs the body exactly once per step from 1 to n, each iteration doing a fixed number (3) of additions — total work = 3·n = O(n). The brute-force recursion instead forms a call tree where each node branches into 3 children down to depth ~n; that tree has on the order of 3n leaves in the worst decomposition, so brute force is bounded above by O(3n) time. A tighter bound comes from the characteristic equation of the recurrence, x³ = x² + x + 1; its dominant real root (the "tribonacci constant") is close to 1.839, giving Θ(1.839n) — we quote this figure rather than derive the root here, but either bound is exponential, which is the point: brute force is unusable well before n reaches the double digits.

Space: array version O(n) for the dp table; rolling version O(1) since only the last 3 values are ever needed — dp[i] never depends on anything before i-3.

Traced example: n = 4

idp[i] rulevalue
0base case (empty climb)1
1dp[0]1
2dp[1]+dp[0]2
3dp[2]+dp[1]+dp[0]4
4dp[3]+dp[2]+dp[1]7

Matches the problem's own example: n=3 → 4 ways, n=4 → 7 ways.

Pitfalls

When to use / when not — trade-offs

Use bottom-up rolling DP whenever the recurrence window is small and fixed (here, 3) — it gives O(n) time, O(1) space, and is trivial to prove correct by induction.

vs. plain recursion (no memo): simpler to write but exponential; only acceptable for tiny n or as a first correctness check before optimizing.

vs. matrix exponentiation: the recurrence is linear, so it can be expressed as a 3×3 matrix power, giving O(log n) time — worth it only if n is huge (e.g. 109) and per-query speed matters; overkill and harder to get right for modest n, and you'd need modular arithmetic anyway since raw counts blow past 64-bit range for large n.

vs. memoized top-down recursion: equivalent time/space to bottom-up but pays recursion-call overhead and risks stack depth issues for large n; bottom-up is preferred once the recurrence direction is obvious.

Takeaways

Recall: If you could take 1, 2, 3, or 4 steps at a time, what does the recurrence for dp[i] become, and what are the new base cases needed?


Derived from the classic staircase / tribonacci-style counting problem; recurrence and complexity analysis are original to this page. The dp[45] value (501,774,317,241) was verified by direct computation of this exact recurrence.

🤖 Don't fully get this? Learn it with Claude

Stuck on Staircase? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Staircase** (DSA) and want to truly understand it. Explain Staircase from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Staircase** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Staircase** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Staircase** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes