Intuition The ONE core idea
A hard problem is often just a small problem asked over and over — Dynamic Programming means solve each small problem once, write the answer on a sticky note, and reuse it forever . Everything on this page exists to earn the symbols and pictures you need before that idea makes full sense.
This page assumes you have seen nothing . Before you can read the parent note Dynamic Programming , you must be fluent in the tiny alphabet below. We build each symbol on the one before it.
Every symbol here orbits one word: subproblem .
A smaller copy of the original problem . If the big task is "compute F ( 5 ) ", then "compute F ( 3 ) " is a subproblem — same kind of question, smaller input.
Picture it as a nesting doll : the big doll (whole problem) contains smaller identical dolls (subproblems) inside it. You cannot understand DP until you see problems this way.
Why the topic needs it: every other symbol below is a way of naming , counting , or storing subproblems. No subproblem, no DP.
F ( n ) — "the answer to the problem when the input is n "
F is a name for a machine . You feed it a number n (the input), and it hands back one answer. F ( 5 ) means "run that machine on input 5 ."
Picture a vending machine : press button n , out drops one answer.
The letter F is just a label — we could call it K , fib , or "the-answer-getter."
The thing in the brackets, n , is the input — the size or state of the problem.
F — which inputs are legal
Fibonacci is only asked about ==whole numbers 0 , 1 , 2 , 3 , … ==. We write this as n ∈ N 0 , where N 0 means "the natural numbers including zero." So valid inputs are n ∈ { 0 , 1 , 2 , … } — never a fraction, never negative. Picture the number line with dots only on the non-negative integers.
Intuition Why we write it this way
Because a subproblem is "the same machine on a smaller input", the notation F ( n − 1 ) literally means "the subproblem one size smaller." The symbol is chosen precisely so that shrinking the input = shrinking the problem. Since n ∈ N 0 , shrinking always lands on another legal input, and the base cases F ( 0 ) , F ( 1 ) stop us before we fall below zero.
An equation where F ( n ) is written ==in terms of smaller inputs of the same F ==. Example, for n ≥ 2 :
F ( n ) = F ( n − 1 ) + F ( n − 2 )
This reads: "the answer at n is the answer at n − 1 plus the answer at n − 2 ."
Why a "+ " here? Because for Fibonacci the whole is literally the sum of two smaller answers. Different problems combine differently (we will see max later) — the combining rule is the heart of each DP.
The smallest input where you already know the answer without shrinking further . For Fibonacci: F ( 0 ) = 0 , F ( 1 ) = 1 . Without a base case the machine calls itself forever. These base cases are exactly why n ∈ N 0 is safe — we stop at 0 and 1 and never ask F ( − 1 ) .
Picture recursion as a tree that grows downward : one call at the top splits into smaller calls, which split again, until every branch hits a base case (a leaf).
Common mistake "Recursion and DP are the same thing."
Why it feels right: DP is built on recursion, so they look identical on paper. The fix: recursion is only the machine ; DP adds a memory so the machine never re-does a call. See §5. Full detail lives in Recursion .
Look again at the tree figure (s02). Find every node labelled F ( 3 ) . In F ( 5 ) 's tree, F ( 3 ) appears twice , F ( 2 ) appears three times . Those repeats are the whole reason DP exists.
Definition Overlapping subproblems (the picture)
When the same node label shows up in more than one place in the recursion tree. Visually: identical dolls appearing again and again.
Definition Distinct subproblems
How many different node labels exist, ignoring repeats. In F ( 5 ) : the distinct ones are F ( 0 ) , F ( 1 ) , F ( 2 ) , F ( 3 ) , F ( 4 ) , F ( 5 ) — that's 6 , i.e. n + 1 . Even though the tree has many nodes (its size grows exponentially — see §4), only n + 1 are truly different.
This gap — many nodes, few distinct — is the exploitable waste. Detailed tree-counting lives in Recursion Trees .
Why the topic needs it: DP's whole payoff is "solve the few distinct ones, skip all the repeats." You cannot see the payoff without seeing the repeats.
O ( g ( n )) — "grows no faster than g "
Here g ( n ) is a simple yardstick function (like n , n 2 , or 2 n ) that we measure our algorithm against. Formally: an algorithm is O ( g ( n )) if, for all large enough n , its work stays below some fixed multiple of g ( n ) . In plain words: "g is a ceiling the running time never breaks through once n is big." O ( 2 n ) means the work is bounded by an exponential; O ( n ) means it grows in a straight line.
Picture two runners:
O ( n ) climbs a gentle ramp .
exponential growth shoots up a near-vertical cliff .
Intuition Why exponential is a catastrophe — and the true branching factor
Each node in the Fibonacci tree spawns (up to) two children, so the tree roughly doubles each level. But the two branches are uneven (F ( n − 1 ) is bigger than F ( n − 2 ) ), so the exact number of nodes grows like Θ ( φ n ) where φ = 2 1 + 5 ≈ 1.618 is the golden ratio — not quite 2 n . Either way it is exponential, and that is the catastrophe. The whole reason DP is a paradigm is that it turns that cliff into a ramp: exponential → O ( n ) . (Θ here means "grows exactly like", a tight version of O .) Deeper treatment in Time Complexity Analysis .
Definition Table (the DP store)
A ==list or grid where slot i holds the answer to subproblem i ==. We write d p [ i ] to mean "the sticky note in slot i ."
Two symbols to read comfortably:
d p [ i ] — a 1-D row of sticky notes (Fibonacci uses this).
d p [ i ] [ c ] — a 2-D grid, one axis per input. Knapsack uses i = item index and c = capacity.
Picture d p [ i ] [ c ] as a spreadsheet : rows are items, columns are capacities, each cell is one stored answer.
Why the topic needs it: the table is the memory that upgrades plain recursion into DP. Without it, §3's repeats are recomputed; with it, each distinct doll is solved once.
max ( a , b )
"==Pick the bigger of a and b ==." Picture a scale: whichever pan is heavier wins.
Before the recurrence, meet its symbols. In the Knapsack Problem we have a list of items; item number i has:
v i = the value of item i (how much it is worth),
w i = the weight of item i (how much room it eats),
c = the capacity remaining in the backpack right now.
K ( i , c ) — the knapsack DP function
K ( i , c ) is our answer-machine name (just like F was for Fibonacci). It means: "the best total value achievable using only items 1 through i when the backpack has room c left." Inputs are whole numbers: i ∈ { 0 , 1 , … , n } and c ∈ { 0 , 1 , … , W } .
Definition Optimal substructure (plain words)
The best answer to the whole is built out of best answers to its parts . Above, the best packing of items 1.. i is literally the better of two smaller best-packings of items 1.. i − 1 .
max and not + ?
Fibonacci adds because the whole is a sum. Knapsack chooses the best option, so it uses max . The combining operator is dictated by what the problem asks — sum, max, min, count. Always ask "what is this problem combining?" before writing the recurrence.
Contrast with Greedy Algorithms (which grabs the locally best option once and never reconsiders) and Divide and Conquer (whose subproblems are all distinct , so no sticky notes help). Other classic optimal-substructure problems: Longest Common Subsequence , Bellman-Ford .
Subproblem = smaller copy
Domain n in naturals with zero
Recurrence F calls smaller F
Base case stops recursion
Overlapping vs distinct subproblems
Table stores each answer once
max and optimal substructure
Every arrow means "you need the left box before the right box makes sense." The topic sits at the bottom because it fuses all these foundations.
Cover the right side and answer out loud before opening the parent note.
What does F ( n ) mean in one sentence? The answer to the problem when the input has size/value n — a machine you feed n and get one answer back.
What is the domain of Fibonacci's F ? The non-negative integers n ∈ N 0 = { 0 , 1 , 2 , … } — no fractions, no negatives.
What is a subproblem? A smaller copy of the same problem (a smaller nesting doll).
What is a base case and why is it required? The smallest input whose answer you know directly; without it the recursion never stops (and it keeps n from going below zero).
In a recursion tree, what does "overlapping subproblems" look like? The same node label appearing in more than one place in the tree.
Distinct subproblems for F ( 5 ) , and how does the node count grow? Only n + 1 = 6 distinct ones, but the total node count grows like Θ ( φ n ) ≈ 1.61 8 n — exponential.
What does O ( g ( n )) formally mean? The running time stays below a fixed multiple of the yardstick function g ( n ) once n is large enough — g is a ceiling.
What is d p [ i ] [ c ] ? A cell in a 2-D table storing the answer to the subproblem indexed by i and c .
Memoization vs tabulation in one line each? Memoization = top-down recursion that checks the table first (lazy); tabulation = bottom-up loop filling smallest first (eager).
What does max ( a , b ) do, and when is it used in DP? Returns the larger of a and b ; used when the problem chooses the best option (e.g. take-or-skip in knapsack).
What are v i , w i , c , and K ( i , c ) in knapsack? v i = value of item i ; w i = its weight; c = capacity left; K ( i , c ) = best value using items 1.. i with room c .
Why does the knapsack recurrence split into three cases? To handle i = 0 (no items), w i > c (item does not fit — skip, guarding against a negative index), and w i ≤ c (choose the better of take/skip).
State optimal substructure in plain words. The best answer to the whole can be built from best answers to its parts.
Why is the combining operator sometimes + and sometimes max ? It matches what the problem asks — Fibonacci sums two answers, knapsack picks the best of two options.
Where does the master formula Time = (#subproblems)×(work each) come from? From summing the fill-cost over every table cell; if each cell costs the same, the sum becomes count × work-per-cell.
Recursion — the machine DP is built on.
Recursion Trees — where overlap becomes visible.
Time Complexity Analysis — the meaning of O ( ⋅ ) .
Memoization vs Tabulation — the two table-filling styles.
Divide and Conquer — disjoint subproblems, so no caching help.
Greedy Algorithms — commits once, never reconsiders.
Knapsack Problem , Longest Common Subsequence , Bellman-Ford — optimal-substructure classics.