Exercises — Dynamic programming — overlapping subproblems, optimal substructure
3.7.6 · D4· Coding › Algorithm Paradigms › Dynamic programming — overlapping subproblems, optimal subst
Level 1 — Recognition
Goal: decide karo ki DP apply bhi hoti hai ya nahi, do-property test "OO" use karke (Overlapping + Optimal substructure).
L1.1
Har problem ke liye batao ki usmein overlapping subproblems hain, optimal substructure hai, dono hain, ya koi nahi: (a) Fibonacci, (b) Merge Sort, (c) unsorted array ka maximum scanning se dhundhna.
Recall Solution
(a) Fibonacci — dono. ka call tree chhote ke liye ko bahut zyada baar recompute karta hai → overlap. Aur literally sub-answers se answer banata hai → optimal substructure. ✅ DP apply hoti hai. (b) Merge Sort — sirf optimal substructure. Poore array ko sort karna dono halves ko sort karne se banta hai, toh substructure hai. Lekin dono halves disjoint index ranges hain — koi bhi subproblem dobara nahi aata, toh koi overlap nahi hai. ⇒ Ye Divide and Conquer hai, DP nahi. Caching yahan zero speedup ke liye memory waste karega. (c) Scanning se Max — kuch bhi nahi (trivially). Ek linear pass hai; koi recursion kuch bhi revisit nahi karta. Cache karne ke liye kuch nahi hai.
L1.2
Ek student longest simple path (koi repeated vertices nahi) ko graph ke do nodes ke beech memoize karta hai. Kya memo se sahi answers milenge?
Recall Solution
Nahi. DP ko optimal substructure chahiye. Longest simple path ke liye ye fail hoti hai: ka best path nahi banta ek independently-best plus best se, kyunki woh pieces vertices reuse kar sakti hain, jo "simple" forbid karta hai. Sub-answers composable nahi hain, toh unhe cache karna galat results deta hai. (Ye bilkul wahi warning hai jo parent note mein hai: memoize karne se pehle substructure prove karo.)
Level 2 — Application
Goal: ek diya hua recurrence haath se execute karo aur table fill karo.
L2.1
, , use karke, tabulation array tak fill karo aur batao.
Recall Solution
Sabse chhote se bade tak fill karo taaki har entry ki dependencies pehle se exist karein: indices ke liye. Toh . Har cell ne sirf use kiya — dono pehle se likhe hue the. Ye optimal substructure concrete form mein hai.
L2.2
0/1 Knapsack. Items (weight, value): , , , . Capacity . DP table fill karo aur max value batao.
Parent note se recurrence yaad karo:

Recall Solution
Rows = items considered , columns = capacity . Row sab zeros hai (koi item nahi). Figure ki grid padhke:
| 0 | 1 | 2 | 3 | 4 | 5 | |
|---|---|---|---|---|---|---|
| 0 (none) | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 (A 2,3) | 0 | 0 | 3 | 3 | 3 | 3 |
| 2 (B 3,4) | 0 | 0 | 3 | 4 | 4 | 7 |
| 3 (C 4,5) | 0 | 0 | 3 | 4 | 5 | 7 |
| 4 (D 5,6) | 0 | 0 | 3 | 4 | 5 | 7 |
Sample cell : skip karo → ; lo → . Max . Answer: ( lo: weight , value ). yahan last column improve nahi karte.
L2.3
Coin change (min coins). Coins , target . amount banane ke liye min coins fill karo.
Recall Solution
. ke liye, .
Answer: (coins ).
Level 3 — Analysis
Goal: correctness aur complexity ke baare mein sochna.
L3.1
Naive Fibonacci kyun hai lekin memoized Fibonacci kyun hai? Recursion tree se argue karo.

Recall Solution
Naive: har node do children spawn karta hai, aur koi memory nahi hai, toh tree roughly har level par double hoti hai → lagbhag nodes, har ek kaam karta hai ⇒ . Figure ki left tree mein do baar, teen baar aata hai — pure repeated kaam. Memoized: pehli baar jab bhi compute hota hai, cache fill ho jaata hai; baad mein har request lookup hai (right tree mein greyed nodes). Sirf distinct values hain, har ek ek baar compute hota hai ⇒ parent ka formula use karke
L3.2
Parent kehta hai knapsack DP hai. Agar aur ho, toh kya ye "polynomial aur isliye fast" hai? Explain karo.
Recall Solution
pseudo-polynomial hai, truly polynomial nahi. ek value hai, aur bits mein iski size hai, toh table mein cells hain lekin input sirf bits ka hai. Yahan cells hain — infeasible, chahe kitna bhi chhota ho. mein fast hai, ke bits mein exponential hai. (Dekho Time Complexity Analysis.)
L3.3
Bellman-Ford mein, saare edges ko baar relax karne se shortest paths sahi kyun milte hain, aur ye DP kaise hai?
Recall Solution
Maano tak at most edges use karke shortest distance. Optimal substructure: tak -edge shortest path kisi neighbour tak -edge shortest path hai, plus edge : Ek simple shortest path at most edges use karta hai, toh full relaxation rounds ke baad har final hai. Har round ek DP layer hai; overlap bahut bada hai kyunki kaafi edges same vertex ko feed karte hain. Ye bilkul (#subproblems)(work) hai.
Level 4 — Synthesis
Goal: khud recurrence derive karo aur dono properties justify karo.
L4.1 — Longest Common Subsequence
Strings (length ) aur (length ) ke liye, ke pehle chars aur ke pehle chars ke Longest Common Subsequence ki length derive karo. Phir "AGCAT" aur "GAC" ka LCS compute karo.
Recall Solution
Derivation. Last characters dekho.
- Agar : woh char zaroor chhote prefixes ke LCS ko extend karega, toh .
- Agar : unme se kam se kam ek common subsequence mein nahi hai, toh .
- Base: (empty prefix).
Optimal substructure: prefixes ka ek optimal LCS chhote prefixes ke optimal LCS se bana hai (swap-in argument). Overlap: aur dono mein recurse karte hain — shared subproblems har jagah hain.
Compute AGCAT (rows), GAC (cols). Table (rows , cols ):
| ∅ | G | A | C | |
|---|---|---|---|---|
| ∅ | 0 | 0 | 0 | 0 |
| A | 0 | 0 | 1 | 1 |
| G | 0 | 1 | 1 | 1 |
| C | 0 | 1 | 1 | 2 |
| A | 0 | 1 | 2 | 2 |
| T | 0 | 1 | 2 | 2 |
LCS length (jaise "AC" ya "GA").
L4.2 — Climbing stairs (variant)
Tum ek baar mein , , ya steps chadh sakte ho. Step tak pahunchne ke kitne distinct tarike hain? Recurrence do aur ke liye compute karo.
Recall Solution
Last move step , , ya se aaya tha. Ye disjoint final moves hain, toh hum counts add karte hain:
Answer: . Optimal substructure = "koi bhi poora tarika exactly ek last hop se khatam hota hai"; overlap = har teen parents dwara reuse hota hai.
Level 5 — Mastery
Goal: properties combine karo, subtle failures pakdo, optimise karo.
L5.1 — Space optimisation
Knapsack table hai. Dikhao ki ye space mein run ho sakta hai, aur woh ek iteration rule batao jo ise sahi banata hai.
Recall Solution
Har row sirf row padhta hai. Toh ek single 1-D array dp[0..W] rakho aur har item ke liye in-place update karo. Lekin ko chahiye — apni left mein ek entry aur old row se. Agar upar ki taraf iterate karo, toh dp[c-w_i] ko new row se overwrite kar doge padhne se pehle (isse ek item do baar liya ja sakta hai — unbounded knapsack). 0/1 ke liye old left value preserve karne ke liye, ko neche ki taraf se tak iterate karo:
for i in range(n):
for c in range(W, w[i]-1, -1):
dp[c] = max(dp[c], v[i] + dp[c-w[i]])Rule: ko descend karo taaki har item at most ek baar use ho. Same time, ab space.
L5.2 — Diagnose the failure
Ek student "longest increasing subsequence, lekin har element do baar use ho sakta hai" ko sirf index par memoize karke solve karta hai. Kuch inputs par wrong answers aate hain. Kaun si property tooti, aur kyun?
Recall Solution
Optimal substructure tooti unki state ke relative mein. Jab "har element ≤ do baar use karo" add hota hai, toh index par answer sirf par nahi balki itni baar har value pehle se use ho chuki hai — us extra history par depend karta hai — woh true subproblem ka hissa hai. Sirf par memoize karne se woh states merge ho jaati hain jo actually alag hain, toh ek cached value ek aisi context mein serve hoti hai jahan wo valid nahi hai. Fix: state ko enlarge karo taaki future jo bhi depend karta hai woh sab capture ho (yahan remaining usage budget), ya prove karo ki reduced state sufficient hai. Ek sahi memo key subproblem ko self-contained banana chahiye.
L5.3 — Choose the paradigm
Fractional knapsack ke liye (, L2.2 jaisi same items, ), kya DP greedy se better hai? Optimal value batao.
Recall Solution
Fractional version ke liye, greedy optimal hai aur DP se simpler hai: value/weight ratio se sort karo aur fill karo. Ratios: , , , . puri lo (2 use, value 3, bachi 3), phir puri lo (3 use, value 4, bachi 0). Total weight , value . Yahan ye 0/1 answer se tie karta hai, lekin generally fractional greedy 0/1 DP. Lesson: DP hamesha sahi hammer nahi hai — jab greedy-choice property hold kare, greedy dono correct bhi hai aur sasta bhi.
Recall Ek-line self-test
Kaun si property DP ko correct banati hai, aur kaun si ise worth it banati hai? Correct ::: Optimal substructure (sub-answers true optimum mein compose hote hain). Worth it ::: Overlapping subproblems (same sub-answer reuse hota hai, toh caching kaam bachata hai).
Connections
- Memoization vs Tabulation — upar exercise ki gayi do implementation styles.
- Knapsack Problem · Longest Common Subsequence · Bellman-Ford — yahan derive ki gayi recurrences.
- Time Complexity Analysis — L3.2 mein pseudo-polynomial subtlety.
- Recursion · Recursion Trees · Divide and Conquer · Greedy Algorithms — paradigm boundaries.