Dynamic Programming
About
Dynamic Programming (DP) is a powerful technique in computer science and mathematics used to solve problems by breaking them down into simpler subproblems and solving each subproblem only once, storing its result for future use. This approach avoids redundant computations, making it highly efficient for problems with overlapping subproblems and optimal substructure properties.
Core Principles
Optimal Substructure: A problem exhibits optimal substructure if the optimal solution to the problem can be constructed from the optimal solutions of its subproblems.
Overlapping Subproblems: The problem can be broken down into subproblems that are solved multiple times during recursion.
Approaches to Solve DP
There are two main approaches to implementing DP:
Top-Down Approach (Memoization)
Bottom-Up Approach (Tabulation)
Top-Down Approach (Memoization)
Solves the problem recursively and stores results of subproblems in a lookup table (memoization) to avoid redundant calculations.
Breaks the problem down first, then builds up solutions.
Uses recursion + caching to store previously computed values.
Steps:
Start solving from the main problem.
Break it into subproblems recursively.
Store the result of each subproblem in a cache (array/map).
Before computing a subproblem, check if it's already solved (memoization).
Bottom-Up Approach (Tabulation)
Solves the problem iteratively by solving smaller subproblems first and building up to the final solution.
Uses loops instead of recursion.
Stores intermediate results in a table (array or list).
Steps:
Identify the smallest subproblems and solve them first.
Use their results to build solutions for larger subproblems.
Store all computed values in a table (array or map).
Return the final solution after computing all subproblems.
Techniques in Dynamic Programming
Dynamic Programming (DP) techniques revolve around solving complex problems by breaking them into overlapping subproblems, solving each subproblem only once, and storing its results to avoid redundant calculations.
1. Memoization (Top-Down Approach)
Definition: Solve the problem recursively while caching (memoizing) the results of subproblems to avoid redundant computations.
Characteristics:
Recursive structure.
Suitable for problems where the recursive relation is straightforward.
Requires extra space for the memoization table.
Example:
Fibonacci sequence:
2. Tabulation (Bottom-Up Approach)
Definition: Build a DP table iteratively from the smallest subproblems to larger subproblems.
Characteristics:
Iterative structure.
Often more space-efficient than memoization.
Preferred for problems where it’s easier to define and build a DP table iteratively.
Example:
Fibonacci sequence:
3. Space Optimization
Definition: Reduce the space complexity of the DP solution by using only the minimum required storage.
Technique:
Instead of storing all states, keep only the last few states needed for computation.
Example:
Space-optimized Fibonacci:
Types of DP Problems
1D DP
Problems where the state depends on one variable.
Examples: Fibonacci numbers, climbing stairs, house robber.
2D DP
Problems with a two-dimensional state space.
Examples: Grid-based pathfinding (e.g., unique paths, minimum path sum), 0/1 Knapsack.
Interval DP
Problems where solutions depend on intervals within an array.
Examples: Matrix chain multiplication, palindrome partitioning.
String DP
Problems related to strings.
Examples: Longest Common Subsequence (LCS), Longest Palindromic Subsequence, Edit Distance.
Subset DP
Problems involving subsets or combinations.
Examples: Subset sum, partition problem, knapsack.
Tree/Graph DP
Problems on trees or graphs.
Examples: Maximum path sum in a tree, longest path in a directed acyclic graph
Last updated
Was this helpful?