Count the work your model creates
Picture
A recipe can be logically correct and still require more work than you can finish. Before choosing an approach, estimate how many situations it examines and what it does in each. Input size helps you reject infeasible plans; it rarely identifies a unique correct algorithm.
Predict
An algorithm has only 1,000 stored states. Does that mean it performs about 1,000 operations?
Reveal the reasoning
No. Each state might scan 1,000 candidates, giving roughly a million candidate checks. State count alone omits transition work. Sorting, copying, and producing the output may add more work.
Go deeper: count before optimizing
For a finite DP, a useful estimate is:
time = sum of work over evaluated states
When each state has the same bound, use number of states × work per state. An array recurrence with n states and two options per state is often O(n). A recurrence comparing every earlier position has O(n²) work even if it uses only one DP array.
def predecessor_checks(n):
return sum(i for i in range(n))
assert predecessor_checks(5) == 10
assert predecessor_checks(1000) == 499500
Typical shapes to recognize: a scan is linear; repeatedly halving a search range takes logarithmically many steps; considering every pair is quadratic; choosing include/exclude for each of n items produces 2**n combinations.
Do not equate nested loops with quadratic time without counting: two pointers that only move forward can each move at most n times in total.
Output matters. Listing all subsets of n distinct items requires 2**n outputs. Copying the elements into separate lists costs Θ(n·2**n) overall. A clever cache cannot make that full output polynomial in n.
Space includes recursion frames and stored output, not just explicit arrays. Big-O here counts abstract operations; Python integers can grow, so arithmetic on enormous counts is not literally constant time.
Analogy limit: estimates are not wall-clock benchmarks. Implementation, constants, input distribution, and available memory still matter.
Change one rule
Instead of listing every subset, return only how many subsets exist. Does the output lower bound still apply?
Check the variation
No. The answer is one integer, 2**n; you no longer have to construct every subset. Its representation still has n + 1 binary digits. Changing the required output can change the whole algorithm.
Connect
Call trees explain repeated work. LIS shows quadratic work with one state coordinate. Subset DP reduces some exponential searches without making them polynomial.