A Systematic Approach to Algorithms

Vijay K. Garg · The University of Texas at Austin

Chapter 10. Dynamic Programming

Classical bottom-up table fills for weighted interval scheduling, longest increasing subsequence, optimal BSTs, and 0/1 knapsack.

This page: Classical forms. View LLP forms »

This page collects the classical implementations of the algorithms developed in this chapter. The lattice-linear (LLP) reformulations and chapter setup live on the LLP companion page.

WeightedIntervalScheduling

Classical DP in two phases: pre-compute $p[\cdot]$, then (1) sweep left to right computing $opt[j] = \max(opt[j-1],\, w_j + opt[p(j)])$ for every $j$, then (2) backtrack from $n$ down to $1$ to reconstruct the actual selected set -- taking $j$ and jumping to $p(j)$ whenever including $j$ was what achieved $opt[j]$, otherwise moving to $j-1$. The backtrack phase is necessary: marking "take" greedily during the forward sweep can select an infeasible, overlapping set even though the forward sweep alone still computes the correct optimal value. $O(n)$ given $p$.

Time complexity: $O(n)$ once $p$ is in hand, $O(n \log n)$ to compute $p$.

LIS

The classical $O(n^2)$ DP: $dp[i] = 1$ initially, then for each $i$, scan all $j < i$ and update $dp[i] := \max(dp[i],\ dp[j] + 1)$ whenever $A[j] < A[i]$.

Time complexity: $O(n^2)$, where $n$ is the size of the array.

OptimalBinarySearchTree

The classical $O(n^3)$ DP: fill $dp[i][j]$ by increasing range length, trying every key $r \in [i, j]$ as the root and combining left/right subtree costs.

Time complexity: $O(n^3)$, where $n$ is the number of keys.

Knapsack01

The classical $O(nW)$ table fill. $G[i][c]$ is the optimum value using items $1..i$ within capacity $c$; row $i$ depends only on row $i-1$.

Time complexity: $O(nW)$, where $n$ is the number of items and $W$ is the capacity.