Skip to content
Part IA Lent Term

Dynamic Programming: The Four Steps

The Four-Step Methodology

Applying dynamic programming to a problem follows a standard pattern:

  1. Characterise the structure of an optimal solution.
  2. Recursively define the value of an optimal solution (the Bellman equation).
  3. Compute the value, typically bottom-up (or top-down with memoisation).
  4. Reconstruct the optimal solution from the computed table (if required, using backpointers).

Example: Virtual Machine Hosting Problem (Rod Cutting)

Given nn CPU cores and a price table p[]p[\ell] for a VM with \ell cores, find the maximum revenue achievable by partitioning cores into VMs.

Step 1: Characterise the optimal structure

An optimal partition for nn cores cuts off a VM of some size ii (earning p[i]p[i]) and optimally partitions the remaining nin - i cores. The first cut must be optimal for its remainder.

Step 2: Recursive definition (Bellman equation)

Let v(j)v(j) be the maximum revenue from jj cores:

v(j)={0if j=0max1ij(p[i]+v(ji))if j>0v(j) = \begin{cases} 0 & \text{if } j = 0 \\[4pt] \max\limits_{1 \le i \le j} \big(p[i] + v(j - i)\big) & \text{if } j > 0 \end{cases}

Step 3: Compute bottom-up

m[0] = 0
for j = 1 to n:
    m[j] = max(p[i] + m[j-i] for i = 1 to j)
return m[n]

Θ(n2)\Theta(n^2) time, Θ(n)\Theta(n) space. Each m[j]m[j] is computed once using O(j)O(j) lookups into already-computed smaller entries. The naive recursive version would be exponential.

Step 4: Reconstruct the solution

Store the choice of ii that achieved the maximum at each jj: choice[j] = i. To reconstruct, start at j=nj = n, output choice[j], subtract it, and repeat until zero.

Example: Weight-Independent Interval Scheduling

Given nn intervals [si,fi)[s_i, f_i), maximise the number of non-overlapping intervals selected.

Step 1: Characterise

Sort intervals by finish time. An optimal schedule either includes the last interval nn (in which case it cannot include any interval overlapping with nn) or excludes nn.

Step 2: Recursive definition

Let p(i)p(i) be the largest index j<ij < i such that interval jj does not overlap with interval ii (i.e. fjsif_j \le s_i). Define:

OPT(i)={0if i=0max(OPT(i1),  1+OPT(p(i)))if i>0\text{OPT}(i) = \begin{cases} 0 & \text{if } i = 0 \\ \max\big(\text{OPT}(i-1),\; 1 + \text{OPT}(p(i))\big) & \text{if } i > 0 \end{cases}

Step 3: Compute

Θ(nlogn)\Theta(n \log n) for sorting by finish time, then Θ(n)\Theta(n) to fill the DP table after precomputing all p(i)p(i).

Step 4: Reconstruct

Trace back: if OPT(i)=OPT(i1)\text{OPT}(i) = \text{OPT}(i-1), skip interval ii. Otherwise include ii and jump to p(i)p(i).

Extracting the Programme

When computing the maximum in Step 3, also record which action achieved it. After filling the table, start from the original problem state and follow the recorded optimal actions to reconstruct the solution. This is equivalent to storing backpointers in a graph of states.

If multiple actions yield the same optimal value, any may be chosen; the problem asks for an optimal solution, not the unique optimal solution.

Summary

StepTask
1Characterise optimal structure
2Write Bellman equation (recursive definition)
3Compute value bottom-up (or memoised top-down)
4Reconstruct solution via backpointers
Key insightIdentify states that maximise subproblem overlap
Common pitfallsExponential without memoisation; wrong state formulation causes poor overlap