Memra

The DP method & rod cutting

◈ 5 cards

The two ingredients of DP, the four-step method, and rod cutting as the canonical example — value + reconstruction.

Why dynamic programming

Dynamic programming (DP) solves an optimization problem by combining solutions to overlapping subproblems, storing each subproblem's answer in a table so it is computed only once. ("Programming" here means a tabular method, as in linear programming — it predates writing code.)

DP applies exactly when a problem has two ingredients:

  1. Optimal substructure — an optimal solution to the whole problem contains optimal solutions to its subproblems.
  2. Overlapping subproblems — a naive recursion solves the same subproblems again and again.

When both hold, DP turns an exponential recursion into a polynomial table fill. Merge sort has neither — its left/right halves never overlap — so memoizing it buys nothing.

The four-step method (memorize this)

  1. Characterize the structure of an optimal solution (find the optimal substructure).
  2. Recursively define the value of an optimal solution (write the recurrence).
  3. Compute that value bottom-up, filling a table.
  4. Reconstruct an optimal solution from stored choices (optional — only if you need which choices, not just the value).

Worked example: rod cutting

A rod of length can be cut into integer pieces; a piece of length sells for price . Maximize total revenue .

Step 1 — substructure. An optimal cut makes a first piece of length (revenue ) and then cuts the remaining length optimally. If the remainder were cut suboptimally we could swap in the better cut for more revenue — contradiction. So:

Step 2 — recurrence.

There are only distinct subproblems () but the naive recursion CUT-ROD calls itself times — that overlap is what DP eliminates.

Step 3 — bottom-up table. Fill in order of increasing length. Each tries all first cuts, so the work is .

Step 4 — reconstruct. Keep a second array = the first-cut length that achieved . To list the cuts: print , set , repeat until . The value table alone cannot tell you which cut won — you need the stored-choice array.

Top-down memoization (recurse, but check the table first) gets the same ; bottom-up just has a smaller constant (no recursion stack).

i=1i=2i=3r(3)8 calls, 4 distincti=1i=2r(2)i=1r(1)r(0)r(0)i=1r(1)r(0)r(0)
Naive CUT-ROD on n = 3: eight calls for only four distinct subproblems. Every highlighted node is a rod length the recursion re-solves from scratch — that repetition is the overlap DP removes, and it doubles with every extra unit of length.
first cut ip[i]r[4-i]p[i] + r[4-i]11892551038194909r[4] = 10, s[4] = 2 — best first cut is length 2.
One cell of the table, computed. r[4] tries every first cut i and reuses the already-known r[4 - i]; the winner is stored in r[4] and the winning i in s[4]. Doing this for j = 1..n is the whole bottom-up algorithm.
12345678910p1589101717202430r15810131718222530s12322612310n=10r[0] = 0 is the base case, off the left of the axis.
The two tables the bottom-up pass produces for the price list used in the exercise. r[j] is the best revenue for length j; s[j] is the first cut that achieved it. Reconstruction chains through s: print s[10] = 10, drop to 10 - 10 = 0, stop — one uncut rod.
NORMAL ~/memra/learn/comp-372/dp-method-and-rod-cutting utf-8 LF