Algorithmic Problem Solving: Conquering Dynamic Programming, Graphs & Asymptotic Time Complexity
Master optimal substructure, overlapping subproblems, memoization vs tabulation, and Dijkstra shortest path graph algorithms.
Dynamic Programming (DP) is one of the most powerful optimization paradigms in computer science, converting exponential time brute-force algorithms O(2^N) into polynomial time O(N) or O(N*W) solutions.
A problem is solvable via Dynamic Programming if it possesses two defining properties: Optimal Substructure (an optimal solution to the problem contains optimal solutions to subproblems) and Overlapping Subproblems (the same subproblems are solved repeatedly).
Top-down memoization caches recursive function evaluations in hash tables, while bottom-up tabulation builds state arrays iteratively, eliminating recursion stack overhead.
In graph theory, breadth-first search (BFS) guarantees shortest paths in unweighted graphs, while Dijkstra algorithm uses priority queues to find single-source shortest paths in non-negative weighted graphs in O((V + E) log V) time.
Key Conceptual Takeaways
- Always verify overlapping subproblems and optimal substructure before designing a DP state table.
- Identify state variables: dp[i][j] representing the optimal metric up to index i with constraint j.
- Tabulation guarantees bounded memory usage and eliminates call-stack recursion overflow risks.
1. The 0/1 Knapsack Canonical State Formulation
In the classical 0/1 Knapsack problem, you are given N items, each with a weight w[i] and value v[i], and a knapsack of maximum capacity W. Because each item can only be taken once (0 or 1), a greedy strategy fails.
Define state dp[i][w] as the maximum value achievable considering the first i items with remaining capacity w. The transition compares omitting item i vs including item i (provided w >= w[i]).
dp[i][w] = \max(dp[i-1][w], \; v[i] + dp[i-1][w - w[i]])
Given items with weights [2, 3, 4] and values [3, 4, 5] and capacity W = 5, compute the maximum value.
Build DP table: With item 1 (w=2, v=3), capacity 2-5 get value 3. With item 2 (w=3, v=4), at capacity 5 we can take item 1 + item 2: value = 3 + 4 = 7. With item 3 (w=4, v=5), taking item 3 leaves capacity 1 (value 0), giving 5 < 7. Optimal total value = 7.
Frequently Asked Questions
What is the computational difference between memoization and tabulation?
Memoization is top-down: it starts at the original problem, recurses down to base cases, and caches answers in a hash map or array. Tabulation is bottom-up: it fills a table from base cases up to the target state, avoiding recursion stack overhead and enabling memory optimizations.
Practice this topic interactively
Get Socratic problem solving, formula step-throughs, and active recall assessments.