cconnected.
Understand the pattern. Find your own way.Find your starting point
Your learning feed/Idea 106 of 218
Ideas this builds on
Thinking in DP106 / 218

DP shares equivalent remaining questions

Picture

Different paths through a search can reach the same unfinished problem. Dynamic programming computes its answer once and reuses it. The difficult part is deciding what “same” means: the state must preserve all information that can change legal continuations or their contribution to the answer.

Predict

You are selecting items, each usable once. Two calls have capacity 5 left, but one may still use item 0 while the other has already considered it. Can best(capacity) safely merge them?

Reveal the reasoning

No. Their available choices differ. A typical state is best(item_index, capacity). For unlimited reuse of the same fixed item types, a different recurrence may legitimately need only capacity.

Go deeper: derive a state before drawing a table

Use a state sentence: “ways(r) is the number of move sequences that consume exactly r remaining steps, using moves 1 or 2.” Fixed move rules are shared context. Previous moves do not affect future legality, so r is enough.

from functools import cache

def count_climbs(n):
    @cache
    def ways(r):
        if r == 0:
            return 1
        if r < 0:
            return 0
        return ways(r - 1) + ways(r - 2)
    return ways(n)

assert count_climbs(5) == 8
assert count_climbs(0) == 1

There are O(n) states and constant transition work per state: O(n) arithmetic operations and O(n) stored answers plus recursion depth. Counting with large integers adds bit-level arithmetic costs.

For an optimization recurrence, explain why the chosen state has optimal substructure: replacing a continuation with a better one for the same state must preserve feasibility and improve or preserve the whole answer. If a hidden history restriction makes the replacement invalid, expand the state.

Counting uses addition over disjoint choices; existence may use any; minimization uses min; maximization uses max. DP is not restricted to optimization. Also, a finite dependency order is needed for these recursive/tabulated DPs: caching completed results does not resolve a cycle of unanswered calls.

Cache keys must be hashable and must include the varying inputs. The nested function keeps this cache scoped to one fixed problem instance; mutating captured inputs while reusing the cache would invalidate its answers.

Analogy limit: DP can share suffix counts, but enumerating full outputs still requires attaching those suffixes to every distinct required prefix.

Change one rule

You receive a bonus only if a size-two move follows a size-one move. Is r sufficient for the best remaining score?

Check the variation

No. The previous move affects the next reward. Store the relevant previous-move information, or derive an equivalent state that preserves that effect.

Connect

Evaluation order comes after the recurrence. Knapsack makes availability explicit. Budget DP adds a coordinate only when its information becomes necessary.