Dynamic programming is the technique that turns “unsolvable in reasonable time” into “solved in milliseconds.” It works by storing solutions to subproblems so you never compute the same thing twice. The challenge is not the technique — it is recognizing when DP applies and identifying the right subproblem structure. This guide teaches both.
⚡ TL;DR: DP applies when: (1) optimal substructure — optimal solution built from optimal sub-solutions, (2) overlapping subproblems — same subproblems solved repeatedly. Two approaches: top-down (recursion + memo cache) or bottom-up (fill table iteratively). Bottom-up avoids call stack overhead.
Recognizing DP problems — dynamic programming
// DP signals in problem statement:
// "minimum/maximum number of..."
// "how many ways to..."
// "is it possible to..."
// "longest/shortest subsequence/path..."
// Any problem where brute force explores exponential possibilities
// Template: ask these questions
// 1. Can I break this into smaller subproblems?
// 2. Do subproblems repeat? (overlapping)
// 3. Does optimal subproblem → optimal full solution? (optimal substructure)
// If yes to all: DP likely appliesProblem 1: Fibonacci (the DP gateway)
// Brute force: O(2^n)
// DP memoization (top-down): O(n)
function fibMemo(n, memo = new Map()) {
if (n <= 1) return n;
if (memo.has(n)) return memo.get(n);
const result = fibMemo(n-1, memo) + fibMemo(n-2, memo);
memo.set(n, result);
return result;
}
// DP tabulation (bottom-up): O(n) time, O(1) space
function fibDP(n) {
if (n <= 1) return n;
let prev = 0, curr = 1;
for (let i = 2; i <= n; i++) [prev, curr] = [curr, prev + curr];
return curr;
}Problem 2: Coin Change (minimum coins)
// Given coins [1,5,10,25] and amount 41, min coins to make change?
// State: dp[i] = minimum coins to make amount i
// Transition: dp[i] = min(dp[i - coin] + 1) for each coin <= i
function coinChange(coins, amount) {
const dp = new Array(amount + 1).fill(Infinity);
dp[0] = 0; // Base case: 0 coins to make amount 0
for (let i = 1; i <= amount; i++) {
for (const coin of coins) {
if (coin <= i && dp[i - coin] + 1 < dp[i]) {
dp[i] = dp[i - coin] + 1;
}
}
}
return dp[amount] === Infinity ? -1 : dp[amount];
}
coinChange([1, 5, 10, 25], 41); // 4: [25, 10, 5, 1]
// Time: O(amount × coins), Space: O(amount)Problem 3: Longest Common Subsequence
// LCS("ABCBDAB", "BDCABA") = 4 ("BCBA")
// State: dp[i][j] = LCS length of s1[0..i-1] and s2[0..j-1]
function lcs(s1, s2) {
const m = s1.length, n = s2.length;
const dp = Array.from({length: m+1}, () => new Array(n+1).fill(0));
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
if (s1[i-1] === s2[j-1]) dp[i][j] = dp[i-1][j-1] + 1;
else dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
}
}
return dp[m][n];
}
// Time: O(m×n), Space: O(m×n)
// Used in: diff tools, DNA sequence alignmentProblem 4: 0/1 Knapsack
// Items with weights and values, bag capacity W, max value?
// Each item: take it (0/1) or leave it
function knapsack(weights, values, W) {
const n = weights.length;
const dp = Array.from({length: n+1}, () => new Array(W+1).fill(0));
for (let i = 1; i <= n; i++) {
for (let w = 0; w <= W; w++) {
// Don't take item i:
dp[i][w] = dp[i-1][w];
// Take item i (if it fits):
if (weights[i-1] <= w) {
dp[i][w] = Math.max(dp[i][w], dp[i-1][w - weights[i-1]] + values[i-1]);
}
}
}
return dp[n][W];
}
// Time: O(n×W), Space: O(n×W) — can optimize to O(W)DP framework cheat sheet
- ✅ Step 1: Define the state — what does dp[i] or dp[i][j] represent?
- ✅ Step 2: Base case — what is dp[0] or dp[0][0]?
- ✅ Step 3: Transition — how does dp[i] relate to dp[i-1], dp[i-2]?
- ✅ Step 4: Answer — where in the table is the final answer?
- ✅ Top-down (memo) if recursion is more intuitive; bottom-up if stack overflow is a risk
- ❌ Never skip drawing the table — it reveals the transition formula visually
DP problems appear frequently in the FAANG system design interview context, and mastering them requires the recursion fundamentals first. External reference: LeetCode DP problems.
Recommended Reading
→ Designing Data-Intensive Applications — Essential for every senior developer. Distributed systems, databases, and production architecture.
→ The Pragmatic Programmer — Timeless engineering wisdom for writing better code at any level.
Affiliate links. We earn a small commission at no extra cost to you.
Free Weekly Newsletter
🚀 Don’t Miss the Next Cheat Code
Join 1,000+ senior developers getting expert-level JS, Python, AWS, system design and AI secrets every week. Zero fluff, pure signal.
Related: CI/CD Pipeline Best Practices: From Code Push to Production in Under 10 Minutes · Functional Programming in JavaScript: Immutability, Pure Functions, and Composition · Day 10: Project: Internal Docs Chat With Citations
Related: Python Dataclasses: 10 Advanced Features That Make __init__ Obsolete · AI Pair Programming Metrics: Cycle Time Without Vanity Accept Scores
Watch: 100 Days of AI on YouTube
Short videos from CheatCoders, one AI engineering topic per day.
Most viewed
- Python Decorators Explained: From Simple Wrappers to Production Patterns
- Claude Code vs Cursor vs GitHub Copilot: Choose by Workflow, and Set Up One Repo That Works With All Three
- AI Agent Frameworks in 2025: LangGraph vs CrewAI vs AutoGen vs Raw API
- Python String Methods: Every str Method With Real Production Examples
- REST API Design Best Practices: The Patterns That Make APIs a Joy to Use
Newly added
- AWS Systems Manager Parameter Store: Hierarchical Runtime Config for Coding Agents
- Amazon Cognito Identity Pools: Federate Coding-Agent Tool Callers Without Long-Lived Keys
- Amazon Athena for Coding Agents: Query Tool Audit Logs and Eval Traces on S3 Without a Warehouse
- AWS Batch for Coding Agents: Parallel Overnight PR Reviews and Long-Running Jobs Without Lambda Timeouts
- Amazon Bedrock Prompt Management: Version and A/B Test Coding-Agent System Prompts
Deep-dive PDF
Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.
Already subscribed? or open the subscribe page.
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.
