Dataslope logoDataslope

Dynamic Programming

Learn memoization, tabulation, and classic dynamic programming patterns in C++

Dynamic programming solves problems by combining answers to overlapping subproblems with optimal substructure. It is the next step after recursion: the Fibonacci tree in recursion.mdx repeats calls; DP stores those answers.

Mindset

Top-down memoization is recursion plus a cache. Bottom-up tabulation fills a table from base cases upward.

Define the state first

Before coding, say exactly what dp[i] or dp[i][j] means. The transition usually follows naturally.

Fibonacci

Naive recursion is exponential because it repeats work.

Code Block
C++ 20 (202002L)
Code Block
C++ 20 (202002L)
Code Block
C++ 20 (202002L)
Code Block
C++ 20 (202002L)

Climbing stairs

If you may climb 1 or 2 steps, f(n) = f(n-1) + f(n-2) because the last move comes from one of those states.

Code Block
C++ 20 (202002L)

Coin change: min coins

Let dp[a] be the minimum coins for amount a; try each coin as the last coin.

Code Block
C++ 20 (202002L)

0/1 knapsack

dp[i][w] is the best value using the first i items and capacity w.

itemweightvalue
0212
1110
2320
3215
Code Block
C++ 20 (202002L)

LCS and LIS

For LCS, dp[i][j] is the best length for prefixes a[0..i) and b[0..j). Example ABCBDAB / BDCABC has length 4.

Code Block
C++ 20 (202002L)

For LIS, dp[i] is the longest increasing subsequence ending at i. The O(n log n) patience-sort version is faster, but O(n²) is the clearest DP.

Code Block
C++ 20 (202002L)

Identifying and optimizing DP

Use DP when you see optimal substructure and overlapping subproblems. Optimize space with rolling arrays when a row only depends on previous rows.

Challenge
C++ 20 (202002L)
Climbing stairs

Implement int climbStairs(int n) for n=1..45. The driver prints several values.

Challenge
C++ 20 (202002L)
Coin change min coins

Implement int coinChange(std::vector<int> coins, int amount). Return -1 if impossible.

Challenge
C++ 20 (202002L)
0/1 Knapsack max value

Implement int knapsack(int W, const std::vector<int>& weights, const std::vector<int>& values).

Check your understanding

QuestionSelect one

When does DP apply best?

Every subproblem is unique.

The problem has optimal substructure and overlapping subproblems.

The input is always sorted.

Only for graphs.

QuestionSelect one

What is top-down DP?

Recursion plus a cache.

Iteration without storage.

Sorting by value.

A binary search tree.

QuestionSelect one

The standard LCS table for lengths n and m costs:

O(n + m)

O(nm)

O(log n)

O(2^n)

QuestionSelect one

Why can Fibonacci use O(1) extra space?

It has no base case.

C++ memoizes automatically.

Each state needs only the previous two values.

It only works for n=10.

On this page