Dynamic Programming II: Knapsack, Coin Change & Rod Cutting

This deck covers 0/1 knapsack, coin change in both its minimum-coin and combination-counting forms, and rod cutting, making the setup explicit every time: define the state in words, write the take-or-skip or best-choice recurrence, pin down the base case, fill the table in dependency order, and reconstruct the items, coins, or cuts actually chosen. It targets four real misconceptions: using a best-ratio greedy strategy on 0/1 knapsack, accidentally reusing a single-copy item, using a greedy coin heuristic on a coin system where it overshoots the true minimum, and an off-by-one in the table's capacity or amount dimension. Every recurrence, table trace, and reconstruction was verified by hand and cross-checked against brute-force enumeration.

Subject: CS3000 Algorithms · 133 slides · symbolic lesson

Open the interactive version of this deck · Homework for this lesson

What this lesson covers

The lesson, slide by slide

1. What you will be able to do

Objectives

This lesson covers three classic dynamic programming problems that all share one skeleton: define a state, write a take-or-skip (or best-choice) recurrence, set a base case, and fill a table in the right order. By the end you can:

  1. Set up the 0/1 knapsack problem: define its state, write its take-or-skip recurrence, and fill its table by hand.
  2. Solve coin change two ways: the fewest coins to make an amount, and the number of distinct ways to make it.
  1. Set up rod cutting as a best-first-cut recurrence and fill its table.
  2. Reconstruct the actual items, coins, or cuts chosen by walking back through a filled table, not just report the optimal number.
  1. Spot four real mistakes: greedy-by-ratio on 0/1 knapsack, reusing a single-copy item, greedy coin choice on a coin system where it fails, and an off-by-one in the table's capacity or amount dimension.

2. What survived from Dynamic Programming I: Memoization?

Warm-up

Discussion prompt

Before we open Dynamic Programming II: Knapsack, Coin Change & Rod Cutting: without looking back, what was the main idea of Dynamic Programming I: Memoization, and what could you do by the end of it that you could not do before?

Hint: One sentence for the idea, one for the skill. If the second one is blank, that is the part to revisit.

Answer:

That deck gives the two ingredients that make dynamic programming apply, then shows the naive exponential recursion for Fibonacci and why it recomputes the same values. It presents the two fixes - top-down memoization and bottom-up tabulation - through a repeatable method for defining the state, writing the recurrence, and choosing the base cases, with Fibonacci and climbing stairs fully hand-traced. It targets four real misconceptions: reaching for dynamic programming when the subproblems never actually overlap, a wrong or missing base case that corrupts an entire table, a memo that is written but never checked before recursing, and a state defined too ambiguously to support a clean recurrence.

3. Toolkit check-in: name them before you look

Concept

Before any new material: cover the screen.

You have named 13 reusable moves so far. Say as many as you can out loud, by number, from memory.

Do not advance until you have actually tried. Getting four of eight is information; skipping the exercise is not.

Here they are. Score yourself.

Today adds no new moves. Every proof in this lesson is built out of the list above. That is the whole point of the list.

The question that starts every proof from here on is not how do I begin. It is which of these applies here?

4. Break it if you can: Toolkit check-in: name them before you look

Counterexample

Discussion prompt

You have named 13 reusable moves so far. Say as many as you can out loud, by number, from memory.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

Answer:

Do not advance until you have actually tried. Getting four of eight is information; skipping the exercise is not.

5. Two ingredients every DP needs

Concept

Every problem in this lesson is solvable by dynamic programming for the same two reasons. First, optimal substructure: the best answer to the whole problem is built out of the best answers to smaller versions of the same problem.

overlapping subproblems — The same smaller subproblem gets asked again and again inside a naive recursive solution. Caching each subproblem's answer once, instead of recomputing it, is exactly what turns exponential recursion into a fast table fill.

Whenever you meet a new problem, check for these two ingredients first. If both are present, a DP table is almost always the right tool.

6. By analogy: Two ingredients every DP needs

Analogy

Discussion prompt

Explain Two ingredients every DP needs by analogy to something with no CS3000 Algorithms in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

Whenever you meet a new problem, check for these two ingredients first. If both are present, a DP table is almost always the right tool.

7. The 0/1 knapsack problem

Concept

You are packing a bag. You have a list of items, each with its own weight and value, and a bag that holds only so much total weight. You may take each item completely or leave it entirely - no cutting an item in half.

The goal: choose the subset of items whose total weight is at or under the bag's capacity, with the largest possible total value.

itemweightvalue
A23
B34
C45
D56

We will trace this exact set of four items through the whole lesson, with a bag capacity of 5.

8. Watch it run: The 0/1 knapsack problem

Pattern

Step through it

Step through The 0/1 knapsack problem one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: item is A
  2. Step 2: item is B
  3. Step 3: item is C
  4. Step 4: item is D

9. The knapsack decision

Picture it

Animation

Shows: The knapsack decision — a rendered Manim animation.

Rendered with Manim.

Takeaway: Both options refer only to the row above, which is why one pass suffices.

10. Why it's called 0/1

Concept

The name 0/1 describes the only two choices available for every item: take zero copies of it, or take exactly one copy. There is no 'take it twice' and no 'take a fraction of it.'

0/1 knapsack — A knapsack variant where each item exists in a single copy and must be taken whole or skipped entirely. Later in this lesson you will meet the opposite kind of decision - unlimited supply - in coin change and rod cutting.

11. Take the definitions apart: overlapping subproblems vs 0/1 knapsack

Definition probe

Sort into buckets

Every line below is part of the definition of overlapping subproblems or of 0/1 knapsack — one or the other, never both. Put each where it belongs.

overlapping subproblems
The same smaller subproblem gets asked again and again inside a naive recursive solution.; Caching each subproblem's answer once, instead of recomputing it, is exactly what turns exponential recursion into a fast table fill.
0/1 knapsack
A knapsack variant where each item exists in a single copy and must be taken whole or skipped entirely.; Later in this lesson you will meet the opposite kind of decision - unlimited supply - in coin change and rod cutting.
b1
The same smaller subproblem gets asked again and again inside a naive recursive solution. Caching each subproblem's answer once, instead of recomputing it, is exactly what turns exponential recursion into a fast table fill.
b2
A knapsack variant where each item exists in a single copy and must be taken whole or skipped entirely. Later in this lesson you will meet the opposite kind of decision - unlimited supply - in coin change and rod cutting.

12. Why the capacity must join the state

Intuition

Imagine deciding whether to take item C. The right choice depends entirely on how much room is left in the bag at that exact moment - item C might be worth taking with 4 units of room free and not worth it with only 1 unit free.

Because the decision changes with the remaining room, remaining room has to be part of what we remember. That is why the state tracks a capacity value, not just which items have been considered.

13. Teach it back: Why the capacity must join the state

Explain it

Discussion prompt

Explain Why the capacity must join the state to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

Because the decision changes with the remaining room, remaining room has to be part of what we remember. That is why the state tracks a capacity value, not just which items have been considered.

14. Defining the state dp[i][w]

Concept

Let the state be: consider only the first so-many items, with a bag of so-much capacity. Store the best total value achievable under exactly those two limits.

\[ dp[i][w] = \text{best value using only the first } i \text{ items, capacity } w \]

The first number can range from zero items considered up to all of them. The second can range from zero capacity up to the bag's full capacity. The final answer is the entry for every item, at the full capacity.

15. The DP Setup skeleton

Concept

Every proof of this kind has the same five or six moves in the same order. The order is not something you rediscover each time.

It is on the right. It will stay on the right through the worked examples that follow.

Why this matters: the structure is now handled. You are not spending working memory on what comes next — you are spending all of it on the one hard step.

Step 1 is where every failed DP fails. A subproblem you cannot say in one sentence is a subproblem you cannot write a recurrence for, and steps 2 through 6 will not rescue it.

16. When greedy coin change IS correct

Picture it

Animation

Shows: When greedy coin change IS correct — a rendered Manim animation.

Rendered with Manim.

Takeaway: Greedy working on your currency is not evidence it works in general.

17. Decision point: the state is named. What is the last decision?

Intuition

What move should we make next?

The subproblem sentence for 0/1 knapsack:

\[ dp[i][w] = \text{the best value using only the first } i \text{ items, with capacity } w \]

Two dimensions, because capacity is a thing you can run out of.

Same move as the stairs and as Kadane. Name it, then say how many cases it produces here.

_Look at your toolkit. Say a move number out loud before this slide advances._ A wrong guess is useful. A silent guess is not.

18. Complete the line: The take-or-skip recurrence

Fill the middle

Fill in the blanks

From The take-or-skip recurrence — finish the line. Write what belongs on the right of the equals sign before you look.

\textdp[i-1][w] dp[i][w] = ___

Why: Producing the right-hand side unprompted is the difference between recognising this line and being able to use it. The best value stays whatever it was using one fewer item, at the same capacity - the new item contributes nothing.

19. The take-or-skip recurrence

Concept

To fill in one entry, look at the newest item under consideration and ask exactly one question: is it better to skip this item, or to take it?

Skip the item

Why: The best value stays whatever it was using one fewer item, at the same capacity - the new item contributes nothing.

\[ \text{skip: } dp[i][w] = dp[i-1][w] \]

Take the item, only if it fits

Why: Add the item's value to the best value achievable with one fewer item and the capacity reduced by this item's weight.

\[ \text{take: } dp[i][w] = dp[i-1][w-\text{weight}_i] + \text{value}_i \]

Whichever option gives the larger value wins.

\[ dp[i][w] = \max\big(dp[i-1][w],\ dp[i-1][w-\text{weight}_i] + \text{value}_i\big) \]

20. Decode the notation: The take-or-skip recurrence

Notation

Annotate

From The take-or-skip recurrence — read this one piece at a time. What is each part doing?

On: \( \text{skip: } dp[i][w] = dp[i-1][w] \)

  • The best value stays whatever it was using one fewer item, at the same capacity - the new item contributes nothing.
  • Add the item's value to the best value achievable with one fewer item and the capacity reduced by this item's weight.

21. The same two moves, third problem running

Concept

The move: #13 (Name the subproblem), then #12 (Case-split on the last decision).

The last decision is about item i, and it has exactly two answers

Why: Either item i is in the chosen set or it is not. Nothing else is possible, so the split is complete by construction.

\[ dp[i][w] = \max\big(\, \underbrace{dp[i-1][w]}_{\text{skip it}}, \;\; \underbrace{v_{i} + dp[i-1][w - w_{i}]}_{\text{take it}} \,\big) \]

Why the take branch goes to i-1 and not to i

Why: Because this is 0/1: once item i is taken it is gone. Sending the take branch back to i would allow reusing it, which is the unbounded problem, not this one.

Both branches drop to i-1. That single detail is the entire difference between 0/1 knapsack and the unbounded version — and it is visible in the recurrence, not in the code.

22. When the next item doesn't even fit

Concept

Sometimes the current item's weight is larger than the remaining capacity in that cell. Then there is no 'take' option to compare against - taking it would require negative remaining room, which is impossible.

\[ \text{if weight}_i > w: \quad dp[i][w] = dp[i-1][w] \]

In that case skipping is not a choice you weigh against taking - it is the only legal option, so the entry simply copies the row above it.

23. Base cases for the knapsack table

Concept

Two edges of the table are known before any recurrence runs. With zero items to choose from, no value can be collected, no matter the capacity.

\[ dp[0][w] = 0 \quad \text{for every } w \]

And with zero capacity, nothing fits, no matter how many items are available.

\[ dp[i][0] = 0 \quad \text{for every } i \]

24. Why knapsack is not actually polynomial

Picture it

Animation

Shows: Why knapsack is not actually polynomial — a rendered Manim animation.

Rendered with Manim.

Takeaway: Doubling the digits of W doubles the table's width many times over.

25. Fill order: row by row, item by item

Concept

Each row only needs values from the row directly above it, so the table fills one full row at a time, in order from the first item to the last.

Within a row, capacities can be filled in any order at all, because a 0/1 knapsack cell only ever depends on the row above it - never on another cell in its own row. Later in this lesson you will meet problems where that is not true.

26. 0/1 knapsack in pseudocode

Concept

Two nested loops fill a table, and the body is a single take-or-skip comparison. The loops are only there to make sure the two cells the comparison needs are already filled.

KNAPSACK(w, v, n, W)
  for cap = 0 to W
    dp[0][cap] = 0
  for i = 1 to n
    for cap = 0 to W
      dp[i][cap] = dp[i-1][cap]
      if w[i] <= cap
        take = v[i] + dp[i-1][cap - w[i]]
        dp[i][cap] = max(dp[i][cap], take)
  return dp[n][W]

Both cells that line 8 and line 6 read come from row i minus one, the row above. That is why the outer loop goes forward over items: the row you need is always the one you just finished.

27. Reading KNAPSACK line by line

Notation

Every line of KNAPSACK says one thing. Read the line, then read what it does — not the other way round.

Annotate

  • The base row: with no items available, every capacity earns zero. This row is filled outright, never computed.
  • Skip item i. The value is whatever was achievable with the earlier items at the same capacity.
  • The guard. An item heavier than the current capacity cannot be taken at all, so the take branch is skipped.
  • Take item i. Its value, plus the best from the row above at the capacity that is left after making room for it.
  • Row i minus one, not row i. Reading your own row would allow taking the same item twice — that is the unbounded problem, not 0/1.
  • The answer is the far corner: all items considered, full capacity available.

28. Step KNAPSACK yourself

Invariant

Every cell asks the same question: the best value using only the first i items, with exactly this much capacity. Say that sentence at each cell before you look at its number.

Step through it

For each cell, name the two cells above it that its value came from.

  1. Line 3: no items: nothing is worth anything
  2. Line 7: item 1 weighs 3, so it does not fit in 0
  3. Line 9: it fits exactly: take it
  4. Line 9: room to spare, still just the one item
  5. Line 9:
  6. Line 6: item 2 weighs 4: skip it at these capacities
  7. Line 9: 5 alone beats 4 alone
  8. Line 9: at capacity 7 both fit: 4 plus 5
  9. Line 10: the answer is the far corner

29. Take or skip, one cell at a time

Picture it

Animation

Shows: KNAPSACK executing: the current line of pseudocode is highlighted while the data it touches changes.

Rendered with Manim.

Takeaway: Take or skip, and both options read only from the row above — which is why filling row by row always works.

30. Time and space complexity of 0/1 knapsack

Concept

The table has one row per item and one column per capacity value, and each cell takes a fixed amount of work to fill.

\[ \text{time} = \Theta(n \cdot W) \]

where the number of items is n and the bag's capacity is W. This is not fast in the size of the input numbers themselves, since W can be large - this running time is called pseudo-polynomial.

\[ \text{space} = \Theta(n \cdot W) \]

for the full table, though it can be trimmed to a single row of size W if the chosen items don't need to be reconstructed afterward.

31. Pricing the knapsack table

Picture it

Animation

Shows: Pricing the knapsack table — a rendered Manim animation.

Rendered with Manim.

Takeaway: States times work per state — the same formula as always.

32. What has to happen first: Filling the knapsack table

Ranking

Put in order

Put the moves of Filling the knapsack table into the order they have to happen.

  1. Row 0: zero items considered
  2. Row 1: consider item A, weight 2 value 3
  3. Row 2: consider item B, weight 3 value 4
  4. Row 3: consider item C, weight 4 value 5
  5. Row 4: consider item D, weight 5 value 6
  6. Verify the final entry against a direct count

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. The base case - every entry is 0 regardless of capacity.

33. Filling the knapsack table

Worked example

Four items, bag capacity 5. Fill dp[i][w] for i from 0 through 4 and w from 0 through 5.

itemweightvalue
A23
B34
C45
D56

Row 0: zero items considered

Why: The base case - every entry is 0 regardless of capacity.

w012345
dp[0][w]000000

Row 1: consider item A, weight 2 value 3

Why: Below capacity 2, A doesn't fit, so the entry copies row 0. From capacity 2 onward, taking A beats skipping it: 3 is bigger than 0.

w012345
dp[1][w]003333

Row 2: consider item B, weight 3 value 4

Why: At capacity 3 and 4, taking B alone (value 4) beats the row above (3). At capacity 5, taking both A and B fits exactly: dp[1][2] plus 4 equals 3 plus 4, or 7, which beats the row above's 3.

w012345
dp[2][w]003447

Row 3: consider item C, weight 4 value 5

Why: At capacity 4, taking C alone (value 5) beats the row above's 4. At capacity 5, taking C plus whatever fits in the remaining unit gives only 5, which loses to the row above's 7 - so C is skipped there.

w012345
dp[3][w]003457

Row 4: consider item D, weight 5 value 6

Why: At capacity 5, taking D alone gives 6, which loses to the row above's 7. D is skipped, and the row is identical to row 3.

w012345
dp[4][w]003457

Verify the final entry against a direct count

Why: The subset containing A and B weighs 2 plus 3, exactly 5, and is worth 3 plus 4, or 7 - matching the final table entry. No other subset within the capacity beats it: D alone is only 6, and adding C or D to A or B always exceeds weight 5.

\[ dp[4][5] = 7 \]

34. The knapsack table, filling in

Picture it

Animation

Shows: The knapsack table, filling in — a rendered Manim animation.

Rendered with Manim.

Takeaway: Every cell asks one question: take this item, or skip it?

35. How to reconstruct the chosen items

Concept

The table tells you the best value, but not which items produced it. For that, walk backward through the table you already filled, one row at a time.

Compare the current cell to the cell directly above it

Why: If the two values are equal, the current item added nothing - it was skipped, so move straight up to the row above at the same capacity.

If the values differ, the item was taken

Why: Record it, then jump to the row above at a reduced capacity: subtract that item's weight before moving up.

\[ \text{if } dp[i][w] \neq dp[i-1][w]: \text{ item } i \text{ taken; go to } dp[i-1][w-\text{weight}_i] \]

Repeat until row 0 or capacity 0 is reached. Every item recorded along the way is part of an optimal choice.

36. Plan first: Reconstructing the chosen items

Step zero

Discussion prompt

Reconstructing the chosen items — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.

Hint: It starts with: Compare dp[4][5] to dp[3][5]

Answer:

  1. Compare dp[4][5] to dp[3][5]
  2. Compare dp[3][5] to dp[2][5]
  3. Compare dp[2][5] to dp[1][5]
  4. Compare dp[1][2] to dp[0][2]
  5. Verify the reconstructed set

37. Reconstructing the chosen items

Worked example

Start at the final answer cell and walk backward using the filled table from before.

w012345
dp[0][w]000000
dp[1][w]003333
dp[2][w]003447
dp[3][w]003457
dp[4][w]003457

Compare dp[4][5] to dp[3][5]

Why: Both are 7 - equal - so item D was skipped. Move up to dp[3][5].

Compare dp[3][5] to dp[2][5]

Why: Both are 7 - equal - so item C was skipped too. Move up to dp[2][5].

Compare dp[2][5] to dp[1][5]

Why: 7 versus 3 - different. Item B was taken. Record B, and move to dp[1][2], since capacity 5 minus B's weight 3 is 2.

Compare dp[1][2] to dp[0][2]

Why: 3 versus 0 - different. Item A was taken. Record A, and move to dp[0][0], since capacity 2 minus A's weight 2 is 0.

Verify the reconstructed set

Why: Items A and B have total weight 2 plus 3, which is 5 and fits exactly, and total value 3 plus 4, which is 7 - matching the table entry. The walk-back recovered exactly the subset found by direct count earlier.

\[ \{A, B\}: \text{ weight } 5,\ \text{value } 7 \]

38. Reconstructing the chosen items — line by line

Picture it

Animation

Shows: Each line of the worked example "Reconstructing the chosen items", appearing one at a time.

The same working the example does, in the order a tutor would write it.

Takeaway: Items A and B have total weight 2 plus 3, which is 5 and fits exactly, and total value 3 plus 4, which is 7 - matching the table entry. The walk-back recovered exactly the subset found by direct count earlier.

39. Why 'best ratio first' seems reasonable

Intuition

A natural instinct: rank every item by value per unit of weight, then grab items in that order until the bag is full. That instinct is exactly correct for a different problem - one where items can be split into fractions.

For 0/1 knapsack, that instinct can lock in an early item that blocks a much better later combination, because a whole item, once taken, can never be partially given back.

40. What feels wrong about taking the best ratio first?

Intuition

What feels wrong about this?

Capacity 10. Two items:

\[ \text{item A: weight } 6, \; \text{value } 30 \quad (\text{ratio } 5) \]

\[ \text{item B: weight } 5, \; \text{value } 20 \quad (\text{ratio } 4) \]

Best ratio first takes A, leaving capacity 4, which fits nothing else. Total: 30.

_Plain English only. No notation, no algebra. Just say what bothers you._

The feeling: there are four units of capacity sitting there doing nothing, and the rule that got you here never considered that.

That feeling is the proof. It is not a substitute for the proof — it is the thing the proof writes down.

Two of item B would weigh 10 and be worth 40. Greedy optimizes the next choice; it cannot see the hole it leaves behind. That hole is exactly what the take-or-skip case split does see, because the skip branch is a real option.

41. Something is wrong here: greedy best-ratio fails for 0/1 knapsack

Anomaly

Predict first

A student writes this, and it looks reasonable:

Capacity 50. Three items, ranked by value per unit of weight.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: Item 1 (ratio 6) fits in 50, leaving 40.

Check every combination that fits in capacity 50 instead of trusting the ratio order.

Why: Item 1 (ratio 6) fits in 50, leaving 40. Item 2 (ratio 5) fits in the remaining 40, leaving 20. Item 3 needs 30 but only 20 remains, so it is skipped entirely - 0/1 allows no partial items.

42. Trap: greedy best-ratio fails for 0/1 knapsack

Trap

The trap

Capacity 50. Three items, ranked by value per unit of weight.

itemweightvaluevalue per weight
110606
2201005
3301204

Take items in order of best ratio: item 1, then item 2

Why: Item 1 (ratio 6) fits in 50, leaving 40. Item 2 (ratio 5) fits in the remaining 40, leaving 20. Item 3 needs 30 but only 20 remains, so it is skipped entirely - 0/1 allows no partial items.

\[ \text{greedy total} = 60 + 100 = 160,\ \text{weight used} = 30 \]

The fix

Check every combination that fits in capacity 50 instead of trusting the ratio order.

subsetweightvalue
items 1,230160
items 1,340180
items 2,350220

Take items 2 and 3, skipping item 1 entirely

Why: Weight 20 plus 30 is 50, fitting exactly, and value 100 plus 120 is 220 - beating every other combination, including the greedy pick of 160. The single highest-ratio item was best left out.

\[ \text{optimal} = 220 > 160 \]

43. Watch it run: Trap: greedy best-ratio fails for 0/1 knapsack

Pattern

Step through it

Step through Trap: greedy best-ratio fails for 0/1 knapsack one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: item is 1
  2. Step 2: item is 2
  3. Step 3: item is 3

44. Plan first: Greedy works for the fractional version

Step zero

Discussion prompt

Greedy works for the fractional version — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.

Hint: It starts with: Take item 1 whole

Answer:

  1. Take item 1 whole
  2. Take item 2 whole
  3. Take two-thirds of item 3
  4. Verify the fractional total uses the full capacity

45. Greedy works for the fractional version

Worked example

Same three items and capacity 50 - but now suppose a fraction of any item can be taken, earning that same fraction of its value. Fill the capacity using best ratio first, allowed this time to slice the last item.

itemweightvaluevalue per weight
110606
2201005
3301204

Take item 1 whole

Why: Ratio 6, the best available, and it fully fits: 10 used, 40 remaining.

\[ \text{running value} = 60,\ \text{remaining capacity} = 40 \]

Take item 2 whole

Why: Ratio 5, next best, and it fully fits: 20 used, 20 remaining.

\[ \text{running value} = 160,\ \text{remaining capacity} = 20 \]

Take two-thirds of item 3

Why: Only 20 of item 3's 30 weight units still fit, so take that fraction, two thirds, of both its weight and its value.

\[ \tfrac{20}{30} \times 120 = 80 \]

Verify the fractional total uses the full capacity

Why: Total weight is 10 plus 20 plus 20, which is 50, exactly the capacity, and total value is 60 plus 100 plus 80, which is 240 - higher than either the 0/1 greedy result of 160 or the 0/1 optimum of 220, because slicing item 3 recovers value 0/1 could never reach.

\[ \text{fractional total} = 240 \]

46. Why greedy fails on coin change

Picture it

Animation

Shows: Why greedy fails on coin change — a rendered Manim animation.

Rendered with Manim.

Takeaway: Taking the biggest coin first is locally sensible and globally wrong.

47. Something is wrong here: accidentally reusing an item

Anomaly

Predict first

A student writes this, and it looks reasonable:

One item only: A, weight 2, value 3. Bag capacity 6. A student writes the recurrence so the 'take' branch looks at the same row instead of the row above.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: Looking at the same row lets item A be counted again in a cell that already used it, so the table effectively allows A to be packed three times: weight 2 plus 2 plus 2 is 6, value 3 plus 3 plus 3 is 9.

Only one physical copy of item A exists. The take branch must look at the row above - one fewer item available - never at the current row.

Why: Looking at the same row lets item A be counted again in a cell that already used it, so the table effectively allows A to be packed three times: weight 2 plus 2 plus 2 is 6, value 3 plus 3 plus 3 is 9.

48. Trap: accidentally reusing an item

Trap

The trap

One item only: A, weight 2, value 3. Bag capacity 6. A student writes the recurrence so the 'take' branch looks at the same row instead of the row above.

\[ \text{wrong take branch: } dp[i][w] = dp[i][w-\text{weight}_i] + \text{value}_i \]

Fill using the same-row take branch

Why: Looking at the same row lets item A be counted again in a cell that already used it, so the table effectively allows A to be packed three times: weight 2 plus 2 plus 2 is 6, value 3 plus 3 plus 3 is 9.

\[ \text{wrong result: } dp[6] = 9\ (\text{three copies of A}) \]

The fix

Only one physical copy of item A exists. The take branch must look at the row above - one fewer item available - never at the current row.

\[ \text{correct take branch: } dp[i][w] = dp[i-1][w-\text{weight}_i] + \text{value}_i \]

Fill using the row-above take branch

Why: With only the row above available, item A can be used at most once. The single copy gives weight 2, value 3, leaving 4 units of capacity unused since nothing else is available to fill it.

\[ \text{correct result: } dp[6] = 3\ (\text{one copy of A}) \]

49. Something is wrong here: off-by-one in the capacity dimension

Anomaly

Predict first

A student writes this, and it looks reasonable:

Same four items, capacity 5. A student sizes the table with 5 columns - for capacities 0 through 4 - thinking 'capacity 5' means 5 columns.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: The column for the actual capacity, 5, was never allocated, so the student reads the entry at capacity 4, which is 5 - undercounting the true optimum by 2.

A capacity of 5 means capacities 0, 1, 2, 3, 4, and 5 are all possible column values - six columns, not five.

Why: The column for the actual capacity, 5, was never allocated, so the student reads the entry at capacity 4, which is 5 - undercounting the true optimum by 2.

50. Trap: off-by-one in the capacity dimension

Trap

The trap

Same four items, capacity 5. A student sizes the table with 5 columns - for capacities 0 through 4 - thinking 'capacity 5' means 5 columns.

w01234
dp[4][w]00345

Read the last available column as the answer

Why: The column for the actual capacity, 5, was never allocated, so the student reads the entry at capacity 4, which is 5 - undercounting the true optimum by 2.

\[ \text{reported answer: } 5\ (\text{wrong}) \]

The fix

A capacity of 5 means capacities 0, 1, 2, 3, 4, and 5 are all possible column values - six columns, not five.

w012345
dp[4][w]003457

Size the table with capacity plus one columns

Why: With the column for capacity 5 correctly included, the entry there reads 7 directly - the true optimum already found by direct count and by walking the table back.

\[ \text{correct answer: } 7 \]

51. Say it in words: Trap: off-by-one in the capacity dimension

Translation

\( \text{correct answer: } 7 \)

Draw it

Translate both ways. First write the expression above as a sentence with no symbols in it at all. Then cover it, and write your sentence back as notation. If the two versions disagree, the disagreement is the thing to fix.

52. Guess the shape of the answer: Double-checking with brute force

Estimation

Predict first

Before trusting a DP table, it helps to see it confirmed against a full listing at least once. List every subset of the four items whose total weight is at most 5.

Commit before you compute: what does Double-checking with brute force come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.

Correct: Verify the table's best row against the DP answer

Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. The largest value among all listed subsets is 7, from A and B together, and no other subset ties or beats it.

53. Double-checking with brute force

Worked example

Before trusting a DP table, it helps to see it confirmed against a full listing at least once. List every subset of the four items whose total weight is at most 5.

subsetweightvalue
none00
A23
B34
C45
D56
A and B57

Rule out every remaining subset

Why: Any subset adding a second item to C or D exceeds weight 5 - for example A with C weighs 6, and A with D weighs 7 - so no other subset needs to be listed.

Verify the table's best row against the DP answer

Why: The largest value among all listed subsets is 7, from A and B together, and no other subset ties or beats it. This matches the filled table's final entry exactly.

\[ \max(0,3,4,5,6,7) = 7 = dp[4][5] \]

54. Watch it run: Double-checking with brute force

Pattern

Step through it

Step through Double-checking with brute force one row at a time. What is driving the change, and what would the row after the last one be?

  1. Step 1: subset is none
  2. Step 2: subset is A
  3. Step 3: subset is B
  4. Step 4: subset is C
  5. Step 5: subset is D
  6. Step 6: subset is A and B

55. The minimum-coins problem

Concept

You have coin denominations available in unlimited supply, and a target amount of money. Find the smallest number of coins that adds up to exactly that amount.

If no combination of coins reaches the amount exactly, that amount is simply unreachable - there is no valid combination to report.

56. Unlimited coins: unbounded, not 0/1

Concept

In 0/1 knapsack, every item could be used at most once. Here, every coin denomination can be used as many times as needed - a coin worth 1 can appear five times in a row if that is the best combination.

unbounded choice — A decision that can be repeated any number of times, as opposed to a 0/1 decision that can be made at most once per item. Coin change and rod cutting are both unbounded; 0/1 knapsack is not.

57. Unbounded coins look backwards, not upwards

Picture it

Animation

Shows: Unbounded coins look backwards, not upwards — a rendered Manim animation.

Rendered with Manim.

Takeaway: Reusing the current row is exactly what allows repeats.

58. Building every amount from smaller change

Intuition

To make change for a large amount, you first need to know the best way to make every smaller amount - the minimum coins for a target is built directly out of the minimum coins for smaller amounts, whichever coin is tried last.

So the table is filled amount by amount, from 0 up to the target, and each entry only ever looks backward at smaller amounts already solved.

59. Loop order decides what you count

Picture it

Animation

Shows: Loop order decides what you count — a rendered Manim animation.

Rendered with Manim.

Takeaway: Two nearly identical programs answering different questions.

60. Process: reaching for the two-dimensional table again

Intuition

Watch me not know the answer. This is what the first two minutes actually look like.

Minimum coins to make an amount, with an unlimited supply of each denomination.

Try the knapsack shape: an entry per coin index and per amount

Why: Knapsack just worked, and this looks like knapsack. Copy the state: dp[i][a] is the fewest coins using the first i denominations to make amount a.

It is correct but the second dimension is doing nothing

Why: Because coins are unlimited, no coin is ever used up. The take branch can go back to i, not i-1 — which means the coin index never actually constrains anything, and every row ends up identical to the row that considers all coins.

Dead end. Not a mistake — a move that was worth trying and did not pay off. This happens in most proofs.

Back up. Drop the dimension that carries no information

Why: The only thing the state needs to remember is the amount remaining. One dimension.

\[ dp[a] = 1 + \min_{c \,\in\, \text{coins},\; c \le a} dp[a - c] \]

The test for whether a dimension belongs in the state: remove it and ask whether the recurrence still has enough information. If it does, it never belonged.

The expert does not see the whole path in advance. The expert tries something, reads the result, and adjusts. That is the skill.

61. Defining the state dp[amount]

Concept

Let the state be a single number: the target amount of money. Store the fewest coins that add up to exactly that amount.

\[ dp[a] = \text{fewest coins that sum to exactly amount } a \]

Unlike knapsack, there is no item-index dimension here - every coin denomination is always available, so the state only needs to track the amount left to build.

62. Complete the line: The recurrence for minimum coins

Fill the middle

Fill in the blanks

From The recurrence for minimum coins — finish the line. Write what belongs on the right of the equals sign before you look.

dp[a] = \min_{c \le a} \big(1 + dp[a-c]\big)

Why: Producing the right-hand side unprompted is the difference between recognising this line and being able to use it. For each coin worth c that is no larger than the amount, using it last means the rest of the amount was already solved optimally.

63. The recurrence for minimum coins

Concept

Try every coin denomination as the last coin added

Why: For each coin worth c that is no larger than the amount, using it last means the rest of the amount was already solved optimally.

\[ dp[a] = 1 + dp[a-c] \quad \text{for each coin } c \le a \]

Take the best choice of last coin

Why: Different coins tried last give different totals; keep whichever one gives the fewest coins overall.

\[ dp[a] = \min_{c \le a} \big(1 + dp[a-c]\big) \]

64. Base case: zero coins for zero amount

Concept

Making an amount of zero needs no coins at all - that is the one fact known before the recurrence runs.

\[ dp[0] = 0 \]

65. Amounts you can't reach

Concept

If every coin denomination is larger than the amount, or every smaller amount it could reduce to is itself unreachable, then the amount cannot be made at all.

Represent that with a placeholder value larger than any real answer could be, often called infinity, so that comparing it against a real coin count always loses, and it never gets mistaken for a valid answer.

\[ dp[a] = \infty \quad (\text{no coin combination reaches } a) \]

66. Time and space complexity of coin change

Concept

The table has one entry per amount from 0 to the target, and filling each entry checks every coin denomination once.

\[ \text{time} = \Theta(\text{amount} \times \text{number of coin denominations}) \]

\[ \text{space} = \Theta(\text{amount}) \]

since the table is just one row this time, not a full grid like knapsack's.

67. Coin change, cell by cell

Picture it

Animation

Shows: Coin change, cell by cell — a rendered Manim animation.

Rendered with Manim.

Takeaway: Each amount looks back at the amounts one coin smaller.

68. Guess the shape of the answer: Filling the minimum-coins table

Estimation

Predict first

Coins available: 1, 3, and 4, in unlimited supply. Target amount: 6. Fill dp[a] for a from 0 through 6.

Commit before you compute: what does Filling the minimum-coins table come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.

Correct: Verify by naming an actual combination

Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. Two coins of value 3 sum to exactly 6, matching the amount-6 entry of 2.

69. Filling the minimum-coins table

Worked example

Coins available: 1, 3, and 4, in unlimited supply. Target amount: 6. Fill dp[a] for a from 0 through 6.

Base case and amount 1

Why: The amount 0 needs 0 coins by definition. For amount 1, only coin 1 fits, giving 1 plus the amount-0 entry, which is 1.

a01
dp[a]01

Amounts 2 and 3

Why: For amount 2, only coin 1 fits: 1 plus the amount-1 entry is 2. For amount 3, coin 1 gives 1 plus the amount-2 entry, or 3, but coin 3 gives 1 plus the amount-0 entry, or 1 - the better choice.

a0123
dp[a]0121

Amount 4

Why: Coin 1 gives 1 plus the amount-3 entry, or 2. Coin 4 gives 1 plus the amount-0 entry, or 1. Coin 4 is best.

a01234
dp[a]01211

Amount 5

Why: Coin 1 gives 1 plus the amount-4 entry, or 2. Coin 3 gives 1 plus the amount-2 entry, or 3. Coin 4 gives 1 plus the amount-1 entry, or 2. The best is 2.

a012345
dp[a]012112

Amount 6

Why: Coin 1 gives 1 plus the amount-5 entry, or 3. Coin 3 gives 1 plus the amount-3 entry, or 2. Coin 4 gives 1 plus the amount-2 entry, or 3. Coin 3 is best.

a0123456
dp[a]0121122

Verify by naming an actual combination

Why: Two coins of value 3 sum to exactly 6, matching the amount-6 entry of 2. No single coin reaches 6, so one coin is impossible, confirming 2 really is the minimum.

\[ 3 + 3 = 6,\ \text{count} = 2 = dp[6] \]

70. Filling the minimum-coins table — line by line

Picture it

Animation

Shows: Each line of the worked example "Filling the minimum-coins table", appearing one at a time.

The same working the example does, in the order a tutor would write it.

Takeaway: Two coins of value 3 sum to exactly 6, matching the amount-6 entry of 2. No single coin reaches 6, so one coin is impossible, confirming 2 really is the minimum.

71. How to reconstruct the coins used

Concept

Walk backward from the target amount, at each step finding which coin was the last one added.

Find the coin that achieves the minimum at this amount

Why: Check every coin c no larger than the current amount; the one where 1 plus the reduced-amount entry equals the current entry was used last.

\[ \text{coin } c \text{ used if } dp[a] = 1 + dp[a-c] \]

Record that coin and move to the smaller amount

Why: Subtract the chosen coin's value from the amount and repeat the search there.

Stop once the amount reaches 0. Every coin recorded along the way is part of an optimal combination.

72. What has to happen first: Reconstructing the coins for amount 6

Ranking

Put in order

Put the moves of Reconstructing the coins for amount 6 into the order they have to happen.

  1. At amount 6, test each coin
  2. At amount 3, test each coin again
  3. Verify the recovered coins

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. Coin 1: 1 plus the amount-5 entry is 1 plus 2, or 3 - not a match.

73. Reconstructing the coins for amount 6

Worked example

Use the filled table from before to walk back from amount 6.

a0123456
dp[a]0121122

At amount 6, test each coin

Why: Coin 1: 1 plus the amount-5 entry is 1 plus 2, or 3 - not a match. Coin 3: 1 plus the amount-3 entry is 1 plus 1, or 2 - a match. Coin 4: 1 plus the amount-2 entry is 1 plus 2, or 3 - not a match.

\[ \text{coin 3 used; move to amount } 6-3=3 \]

At amount 3, test each coin again

Why: Coin 1: 1 plus the amount-2 entry is 1 plus 2, or 3 - not a match, since the amount-3 entry is 1. Coin 3: 1 plus the amount-0 entry is 1 plus 0, or 1 - a match.

\[ \text{coin 3 used; move to amount } 3-3=0 \]

Verify the recovered coins

Why: The walk-back recorded coin 3 twice, for a total of 3 plus 3, which is 6, using 2 coins - matching the amount-6 entry and the combination already confirmed by direct count.

\[ \{3, 3\}: \text{sum } 6,\ \text{count } 2 \]

74. Reconstructing the coins for amount 6 — line by line

Picture it

Animation

Shows: Each line of the worked example "Reconstructing the coins for amount 6", appearing one at a time.

The same working the example does, in the order a tutor would write it.

Takeaway: The walk-back recorded coin 3 twice, for a total of 3 plus 3, which is 6, using 2 coins - matching the amount-6 entry and the combination already confirmed by direct count.

75. Something is wrong here: greedy coin choice overshoots the minimum

Anomaly

Predict first

A student writes this, and it looks reasonable:

Coins 1, 3, and 4. Target amount 6. A student always grabs the largest coin that still fits, the way familiar coin systems usually allow.

It is wrong. Say what breaks — and say it before you turn the page.

Correct: Take a 4, leaving 2. Take a 1, leaving 1.

Check the DP table filled earlier instead of assuming the biggest coin first is always safe.

Why: Take a 4, leaving 2. Take a 1, leaving 1. Take another 1, leaving 0. Three coins total: 4 plus 1 plus 1.

76. Trap: greedy coin choice overshoots the minimum

Trap

The trap

Coins 1, 3, and 4. Target amount 6. A student always grabs the largest coin that still fits, the way familiar coin systems usually allow.

\[ \text{coins available, largest first: } 4, 3, 1 \]

Greedily take the largest coin each time

Why: Take a 4, leaving 2. Take a 1, leaving 1. Take another 1, leaving 0. Three coins total: 4 plus 1 plus 1.

\[ \text{greedy result: } 3 \text{ coins } (4+1+1=6) \]

The fix

Check the DP table filled earlier instead of assuming the biggest coin first is always safe.

\[ dp[6] = 2 \]

Use two coins of value 3 instead

Why: 3 plus 3 is 6, using only 2 coins - beating the greedy result of 3. On this coin system, the 'grab the biggest coin' rule genuinely gives the wrong answer; it only works for coin systems specially designed to make it safe.

\[ \text{optimal: } 2 \text{ coins } (3+3=6) < 3 \]

77. Which of these survive contact with Dynamic Programming II: Knapsack, Coin…?

Two truths and a lie

Sort into buckets

Some of these hold up and some are the exact mistakes this lesson is built to prevent. Sort them.

Holds up
You have named 13 reusable moves so far. Say as many as you can out loud, by number, from memory.; Whenever you meet a new problem, check for these two ingredients first. If both are present, a DP table is almost always the right tool.; The goal: choose the subset of items whose total weight is at or under the bag's capacity, with the largest possible total value.
Breaks
Capacity 50. Three items, ranked by value per unit of weight.; One item only: A, weight 2, value 3. Bag capacity 6. A student writes the recurrence so the 'take' branch looks at the same row instead of the row above.
sound
These are stated as this lesson states them — each one survives the edge cases Dynamic Programming II: Knapsack, Coin Change & Rod Cutting puts it through.
flawed
Each of these is lifted from a trap in this deck: reasonable-sounding, and wrong in a way that only shows up once you rely on it.

78. A different question: how many ways, not how few

Concept

Same coins, same target amount - but now the question changes completely. Instead of the fewest coins, count every distinct combination of coins that sums to the amount, where order does not matter.

Using a coin of value 1 then one of value 2 is the same combination as using a coin of value 2 then one of value 1 - they use the same collection of coins, just listed in a different order.

79. Why counting by amount alone double-counts

Intuition

If the state only tracked the amount, and coins were scanned through in any order at every amount, the same combination could be built in more than one order and get counted twice.

To count combinations instead of orderings, process the coin denominations one type at a time - fully deciding how many of the first coin type to use before ever considering the second type - so each combination is only ever built in one fixed order.

80. Defining the state dp[i][a]

Concept

This state needs two numbers: how many coin types have been made available so far, and the amount being built.

\[ dp[i][a] = \text{ways to make amount } a \text{ using only the first } i \text{ coin types} \]

The coin-type dimension is what keeps every combination counted exactly once, no matter what order the coin types happen to be listed in.

81. Decision point: how many ways, not how few coins

Intuition

What move should we make next?

Same coins, different question. Compare the two states:

\[ \text{minimum coins: } \; dp[a] \qquad \text{counting ways: } \; dp[i][a] \]

The counting version needs the coin index back. The minimum version did not.

Why does counting need a dimension that minimizing did not? Answer before the recurrence appears.

_Look at your toolkit. Say a move number out loud before this slide advances._ A wrong guess is useful. A silent guess is not.

82. The recurrence for counting ways

Concept

Don't use this coin type at all

Why: Every way to make the amount without this coin type was already counted using one fewer coin type.

\[ \text{without coin } i: \ dp[i-1][a] \]

Use at least one of this coin type

Why: Use one copy of coin i now, and count the remaining ways to make what's left - still allowing this same coin type again, since supply is unlimited.

\[ \text{with coin } i: \ dp[i][a - \text{value}_i] \]

Add the two counts together, since 'without this coin type' and 'with at least one' never overlap.

\[ dp[i][a] = dp[i-1][a] + dp[i][a-\text{value}_i] \]

83. The fractional version is greedy

Picture it

Animation

Shows: The fractional version is greedy — a rendered Manim animation.

Rendered with Manim.

Takeaway: One word in the problem statement changes the whole technique.

84. Why coins go on the outside loop

Concept

Notice the 'use this coin type' branch points at the same row, not the row above. That is only safe because the coin-type loop is the outer loop and the amount loop is the inner one - every cell in a row is filled left to right before moving to the next row.

If the loops were swapped - amounts on the outside, coin types on the inside - that same-row dependency would break, and the count would silently include orderings as if they were separate combinations.

85. Base cases for counting ways

Concept

With zero coin types available, there is exactly one way to make the amount zero - use nothing - and zero ways to make any positive amount, since there is nothing to build it from.

\[ dp[0][0] = 1, \qquad dp[0][a] = 0 \ \text{for } a > 0 \]

86. Getting the base cases right

Picture it

Animation

Shows: Getting the base cases right — a rendered Manim animation.

Rendered with Manim.

Takeaway: The whole first row and first column, filled before anything else.

87. Plan first: Filling the counting-ways table

Step zero

Discussion prompt

Filling the counting-ways table — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.

Hint: It starts with: Row for zero coin types

Answer:

  1. Row for zero coin types
  2. Row for coin types {1}
  3. Row for coin types {1, 2}, amounts 0 through 2
  4. Amounts 3 and 4
  5. Check the arithmetic in the final cell

88. Filling the counting-ways table

Worked example

Coin types available, in order: value 1, then value 2. Target amount: 4.

Row for zero coin types

Why: Base case: exactly one way to make 0, using nothing, and zero ways to make anything positive.

a01234
dp[0][a]10000

Row for coin types {1}

Why: Every amount can only be built from 1's, so there is exactly one way to make each amount: all 1's.

a01234
dp[1][a]11111

Row for coin types {1, 2}, amounts 0 through 2

Why: Amount 0 gives 1, copied from the row above. Amount 1 also copies the row above, since a coin of 2 can't fit into amount 1. Amount 2 combines the row-above value 1 with the same-row value at amount 0, giving 1 plus 1, or 2 - either four... two 1's, or one 2.

a012
dp[2][a]112

Amounts 3 and 4

Why: Amount 3 combines the row-above value 1 with the same-row value at amount 1, giving 1 plus 1, or 2. Amount 4 combines the row-above value 1 with the same-row value at amount 2, giving 1 plus 2, or 3.

a01234
dp[2][a]11223

Check the arithmetic in the final cell

Why: The amount-4 entry combines the row-above value at amount 4, which is 1 (all four coins are 1's), with the same-row value at amount 2, which is 2 (the ways to make 2, each with an extra coin of value 2 added on top): 1 plus 2 is 3.

\[ dp[2][4] = 1 + 2 = 3 \]

89. Counting ways, not minimising

Picture it

Animation

Shows: Counting ways, not minimising — a rendered Manim animation.

Rendered with Manim.

Takeaway: Same table, different recurrence — count instead of minimise.

90. Plan first: Verifying by listing every way to make 4

Step zero

Discussion prompt

Verifying by listing every way to make 4 — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.

Hint: It starts with: List the combination that uses only 1's

Answer:

  1. List the combination that uses only 1's
  2. List the combination with exactly one coin of value 2
  3. List the combination with two coins of value 2
  4. Verify the count matches the table

91. Verifying by listing every way to make 4

Worked example

List every combination of coins worth 1 and 2 that sums to exactly 4, to check the table's count of 3 directly.

List the combination that uses only 1's

Why: Four coins of value 1: 1 plus 1 plus 1 plus 1 is 4. That is one combination.

List the combination with exactly one coin of value 2

Why: One 2 and two 1's: 2 plus 1 plus 1 is 4. That is a second, distinct combination - the order the coins are listed in doesn't create new ones.

List the combination with two coins of value 2

Why: Two 2's: 2 plus 2 is 4. That is a third combination. No combination can use three or more 2's, since three 2's already sum to 6, exceeding 4.

Verify the count matches the table

Why: Exactly three distinct combinations were found - four 1's, one 2 with two 1's, and two 2's - matching the table's entry of 3 for amount 4 with coin types 1 and 2.

\[ 3 \text{ combinations} = dp[2][4] \]

92. Work backwards from the answer: Verifying by listing every way to make 4

Reverse engineer

Discussion prompt

Work backwards. The example finished here:

Verify the count matches the table

What was it asked to do, and what must it have been given? Reconstruct the problem from its answer.

Hint: Every quantity in the result had to enter somewhere. Account for each one.

Answer:

List every combination of coins worth 1 and 2 that sums to exactly 4, to check the table's count of 3 directly.

93. The rod-cutting problem

Concept

You have a metal rod of a certain length and a price list telling you what each length of piece sells for. Cut the rod into any number of pieces, of any lengths that add up to the original length, to maximize total revenue.

length12345
price158910

We will trace a rod of length 5 with this exact price list through the rest of this section.

94. Unlimited pieces of every length

Intuition

Nothing stops a cut piece of length 2 from appearing twice in the same rod - pieces are just lengths, and every length is available as many times as the remaining rod allows.

That makes rod cutting an unbounded decision, like coin change, not a 0/1 decision like knapsack - there is no separate physical copy of each length to run out of.

95. Defining the state dp[len]

Concept

The state is a single number: the length of rod still to be cut. Store the best total revenue obtainable from a rod of exactly that length.

\[ dp[\text{len}] = \text{best revenue from a rod of length len} \]

96. The recurrence: best first cut plus the rest

Concept

Instead of a take-or-skip choice, rod cutting asks: how long should the very first piece be? Try every possible length for that first piece, then solve the remaining rod the same way.

\[ dp[\text{len}] = \max_{1 \le i \le \text{len}} \big(\text{price}_i + dp[\text{len} - i]\big) \]

Because every remaining piece will also eventually be treated as 'the first piece' of what's left, this one formula automatically considers every possible way to split the whole rod.

97. Why rod cutting needs only one dimension

Concept

Knapsack's state needed an item-index dimension because each item could be used at most once, and the recurrence had to remember how many items had already been considered.

Rod cutting has no such restriction - every length of first piece is available at every step, considered fresh each time - so the state only ever needs to track the length still remaining.

98. Each row needs only the row above

Picture it

Animation

Shows: Each row needs only the row above — a rendered Manim animation.

Rendered with Manim.

Takeaway: Which is why one array of length W is enough if you sweep the right way.

99. Base case: a zero-length rod earns nothing

Concept

A rod with no length left to cut produces no pieces and no revenue. That is the one fact known before the recurrence runs.

\[ dp[0] = 0 \]

100. Teach it back: Base case: a zero-length rod earns nothing

Explain it

Discussion prompt

Explain Base case: a zero-length rod earns nothing to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.

Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.

Answer:

A rod with no length left to cut produces no pieces and no revenue. That is the one fact known before the recurrence runs.

101. Time and space complexity of rod cutting

Concept

The table has one entry per rod length from 0 up to the original length, and filling each entry tries every shorter first-cut length.

\[ \text{time} = \Theta(n^2) \]

where n is the rod's original length, since the entry for length n tries up to n different first cuts.

\[ \text{space} = \Theta(n) \]

102. By analogy: Time and space complexity of rod cutting

Analogy

Discussion prompt

Explain Time and space complexity of rod cutting by analogy to something with no CS3000 Algorithms in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.

Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.

Answer:

The table has one entry per rod length from 0 up to the original length, and filling each entry tries every shorter first-cut length.

103. Guess the shape of the answer: Filling the rod-cutting table

Estimation

Predict first

Price list for lengths 1 through 5: 1, 5, 8, 9, 10. Fill dp[len] for len from 0 through 5.

Commit before you compute: what does Filling the rod-cutting table come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.

Correct: Verify the final entry against a direct combination

Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. Cutting the rod into a piece of length 2 and a piece of length 3 gives revenue 5 plus 8, which is 13 - matching the table's final entry.

104. Filling the rod-cutting table

Worked example

Price list for lengths 1 through 5: 1, 5, 8, 9, 10. Fill dp[len] for len from 0 through 5.

length12345
price158910

Length 0 and 1

Why: Length 0 is the base case, worth 0. For length 1, the only first cut is length 1 itself: price 1 plus the length-0 entry, which is 1.

len01
dp[len]01

Length 2

Why: A first cut of length 1 gives price 1 plus the length-1 entry, or 2. A first cut of length 2 gives price 5 plus the length-0 entry, or 5. The whole-piece cut wins.

len012
dp[len]015

Length 3

Why: Length-1 first cut: price 1 plus the length-2 entry, or 6. Length-2 first cut: price 5 plus the length-1 entry, or 6. Length-3 first cut: price 8 plus the length-0 entry, or 8. Selling it whole wins.

len0123
dp[len]0158

Length 4

Why: Length-1: 1 plus 8 is 9. Length-2: 5 plus 5 is 10. Length-3: 8 plus 1 is 9. Length-4: 9 plus 0 is 9. Cutting off a length-2 piece first wins.

len01234
dp[len]015810

Length 5

Why: Length-1: 1 plus 10 is 11. Length-2: 5 plus 8 is 13. Length-3: 8 plus 5 is 13. Length-4: 9 plus 1 is 10. Length-5: 10 plus 0 is 10. The best is 13, tied between first cuts of length 2 and length 3.

len012345
dp[len]01581013

Verify the final entry against a direct combination

Why: Cutting the rod into a piece of length 2 and a piece of length 3 gives revenue 5 plus 8, which is 13 - matching the table's final entry. Selling the rod whole only earns 10, confirming that cutting is worth it here.

\[ dp[5] = 13 = 5 + 8 \]

105. Filling the rod-cutting table — line by line

Picture it

Animation

Shows: Each line of the worked example "Filling the rod-cutting table", appearing one at a time.

The same working the example does, in the order a tutor would write it.

Takeaway: Cutting the rod into a piece of length 2 and a piece of length 3 gives revenue 5 plus 8, which is 13 - matching the table's final entry. Selling the rod whole only earns 10, confirming that cutting is worth it here.

106. Complete the line: How to reconstruct the cuts

Fill the middle

Fill in the blanks

From How to reconstruct the cuts — finish the line. Write what belongs on the right of the equals sign before you look.

\text\text{price}_i + dp[\text{len}-i] i \text___ dp[\text___] = ___

Why: Producing the right-hand side unprompted is the difference between recognising this line and being able to use it. Check every possible first-cut length from 1 up to the current length; the one where its price plus the remaining rod's best revenue equals the table entry is the one that was used.

107. How to reconstruct the cuts

Concept

Walk backward from the full rod length, at each step finding which first-cut length actually achieved the best revenue.

Find the winning first-cut length at the current length

Why: Check every possible first-cut length from 1 up to the current length; the one where its price plus the remaining rod's best revenue equals the table entry is the one that was used.

\[ \text{first cut } i \text{ used if } dp[\text{len}] = \text{price}_i + dp[\text{len}-i] \]

Record that piece length and move to the remaining rod length

Why: Subtract the chosen first-cut length from the current length and repeat the search there.

Stop once the remaining length reaches 0. Every piece length recorded is part of an optimal set of cuts.

108. Decode the notation: How to reconstruct the cuts

Notation

Annotate

From How to reconstruct the cuts — read this one piece at a time. What is each part doing?

On: \( \text{first cut } i \text{ used if } dp[\text{len}] = \text{price}_i + dp[\text{len}-i] \)

  • Check every possible first-cut length from 1 up to the current length; the one where its price plus the remaining rod's best revenue equals the table entry is the one that was used.
  • Subtract the chosen first-cut length from the current length and repeat the search there.

109. What has to happen first: Reconstructing the cuts for length 5

Ranking

Put in order

Put the moves of Reconstructing the cuts for length 5 into the order they have to happen.

  1. At length 5, test each first-cut length
  2. At length 3, test each first-cut length
  3. Verify the recovered cuts

Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. Length 1: price 1 plus the length-4 entry is 1 plus 10, or 11 - not a match.

110. Reconstructing the cuts for length 5

Worked example

Use the filled table to walk back from length 5.

len012345
dp[len]01581013

At length 5, test each first-cut length

Why: Length 1: price 1 plus the length-4 entry is 1 plus 10, or 11 - not a match. Length 2: price 5 plus the length-3 entry is 5 plus 8, or 13 - a match. Length 3 also matches, but the search follows the first match found.

\[ \text{first cut } 2 \text{ used; remaining length } 5-2=3 \]

At length 3, test each first-cut length

Why: Length 1: price 1 plus the length-2 entry is 1 plus 5, or 6 - not a match. Length 2: price 5 plus the length-1 entry is 5 plus 1, or 6 - not a match. Length 3: price 8 plus the length-0 entry is 8 plus 0, or 8 - a match.

\[ \text{first cut } 3 \text{ used; remaining length } 3-3=0 \]

Verify the recovered cuts

Why: The walk-back recorded pieces of length 2 and length 3, which sum to 5, the original rod length, and whose prices sum to 5 plus 8, or 13 - matching the table's final entry exactly.

\[ 2 + 3 = 5,\quad 5 + 8 = 13 = dp[5] \]

111. Decision point: three problems, one procedure

Intuition

What move should we make next?

Knapsack, coin change and rod cutting, all solved today.

For each one, say the subproblem sentence and the last decision, from memory, without scrolling back.

If you can produce all six from memory, you own the procedure. If you can only produce the recurrences, you memorized three answers.

_Look at your toolkit. Say a move number out loud before this slide advances._ A wrong guess is useful. A silent guess is not.

112. Every item poses one binary question

Picture it

Animation

Shows: Every item poses one binary question — a rendered Manim animation.

Rendered with Manim.

Takeaway: Two branches per item, and the table stops it becoming two to the n.

113. Comparing the three setups side by side

Concept

All three problems share the same skeleton - state, recurrence, base case, fill order, reconstruction - but differ in exactly how many times each choice can be used.

problemstatechoice typetable shape
0/1 knapsackitems considered, capacitytake at most once2 dimensions
minimum coinsamounttake any number of times1 dimension
counting wayscoin types considered, amounttake any number of times2 dimensions
rod cuttinglength remainingtake any number of times1 dimension

114. Which is which, by choice type

Discrimination

Sort into buckets

Sort these by choice type, from memory, without looking back at Comparing the three setups side by side. Telling them apart on the spot is the skill; the table is only where the answer happens to be written down.

take at most once
0/1 knapsack
take any number of times
minimum coins; counting ways; rod cutting
g1
choice type is "take at most once" for 0/1 knapsack — that is what the table on "Comparing the three setups side by side" records, and it is the single property separating this group from the rest.
g2
choice type is "take any number of times" for minimum coins, counting ways, rod cutting — that is what the table on "Comparing the three setups side by side" records, and it is the single property separating this group from the rest.

115. A DP table is a table you can trust

Intuition

Every entry in a correctly filled table is a small, already-proven fact - the best value, count, or revenue for a smaller version of the same problem. Reading the final cell is not a guess; it is the last link in a chain of facts you built yourself.

That is why filling the table in the right order matters so much: every cell must only ever look at cells that are already known facts, never at a cell still waiting to be filled.

116. The five-step DP setup recipe

Pattern

1. Define the state in plain words

Why: Name exactly what a table entry represents before writing any formula - what is fixed, and what does the entry store?

2. Write the recurrence: what are the actual choices?

Why: Enumerate every option for extending a solution - skip versus take once, or try every possible last coin or first cut - and combine them with a max, min, or sum, whichever the problem asks for.

3. Pin down the base case

Why: Identify the smallest instance whose answer is obvious without any recurrence, and start filling from there.

4. Choose a fill order that respects the dependencies

Why: Every cell must only depend on cells already filled - the row above for 0/1 choices, the same row for unbounded ones.

5. Plan the reconstruction alongside the recurrence

Why: At each cell, know how to tell which choice produced its value, so the actual items, coins, or cuts can be recovered by walking backward, not just their count.

117. Where this shows up: Dynamic Programming II: Knapsack, Coin Change &…

Real world

Discussion prompt

Outside this lesson: where does Dynamic Programming II: Knapsack, Coin Change & Rod Cutting actually turn up? Name one concrete situation — a job, a piece of software someone ships, a decision somebody has to make — and say which part of The five-step DP setup recipe is doing the work in it.

Hint: Vague is the failure mode here. "Engineering" is not a situation; "deciding whether this build is fast enough to ship" is.

Answer:

0/1 knapsack, minimum-coin and combination-counting coin change, and rod cutting, taught with the setup made explicit every time: define the state in words, write the take-or-skip (or best-choice) recurrence, pin the base case, fill the table in dependency order, and reconstruct the actual items, coins, or cuts chosen. Targets four real misconceptions: using a best-ratio greedy strategy on 0/1 knapsack, accidentally reusing a single-copy item, using a greedy coin heuristic on a coin system where it overshoots the true minimum, and an off-by-one in the table's capacity or amount dimension.

118. Check yourself: the knapsack recurrence

Check

Consider one cell of a 0/1 knapsack table. The item under consideration has weight 4 and value 6. The remaining capacity at this cell is 3.

Check your understanding

What must this table entry equal?

  • A. The entry directly above it, because the item doesn't fit and skipping is the only option. (correct)
  • B. The entry above at capacity minus 4, plus 6, since taking it is still worth trying.
  • C. The entry in the same row at capacity minus 4, plus 6, taking the item from the current row.
  • D. 0, since nothing fits in this cell.

Answer: A

Why: Weight 4 is larger than the remaining capacity of 3, so the take branch is not a legal option here - it would require negative remaining capacity. The only legal value is copying the entry directly above, at the same capacity.

Why B tempts people
This computes a take branch anyway, but weight 4 does not fit inside capacity 3, so this branch is not defined here - it requires a non-negative remaining capacity.
Why C tempts people
This uses the same-row take branch, which is the unbounded, reuse-allowed recurrence, not 0/1 knapsack's - and it has the same fitting problem as choice B.
Why D tempts people
This assumes nothing at all can be carried forward, but the row above already holds a value from earlier items, and that value should be copied even when the newest item doesn't fit.

119. Rule out three: Check yourself: greedy versus 0/1

Elimination

Eliminate the wrong options

What does the correct 0/1 knapsack answer give for capacity 10?

3 of these 4 are wrong. Strike them one at a time, and say what rules each one out before you strike the next. The survivor is the answer.

  • A. 50, by taking item 2 alone instead of following the ratio order.
  • B. 30, matching the greedy ratio order.
  • C. 80, by taking both items.
  • D. 0, since neither item fits.

Survives elimination: A

Why: Item 2 alone weighs 10 and fits exactly in capacity 10, earning value 50 - more than item 1's 30. Checking every subset, not just the ratio order, is what the 0/1 recurrence does automatically, and it finds 50 is optimal.

120. Check yourself: greedy versus 0/1

Check

Two items: weight 5, value 30; and weight 10, value 50. Capacity 10. Greedy by ratio picks the first item only (it fits, leaving 5, and the second item needs 10, which no longer fits), for a total of 30.

\[ \text{item 1: weight 5, value 30}\quad\text{item 2: weight 10, value 50} \]

Check your understanding

What does the correct 0/1 knapsack answer give for capacity 10?

  • A. 50, by taking item 2 alone instead of following the ratio order. (correct)
  • B. 30, matching the greedy ratio order.
  • C. 80, by taking both items.
  • D. 0, since neither item fits.

Answer: A

Why: Item 2 alone weighs 10 and fits exactly in capacity 10, earning value 50 - more than item 1's 30. Checking every subset, not just the ratio order, is what the 0/1 recurrence does automatically, and it finds 50 is optimal.

Why B tempts people
This is the greedy-by-ratio result, which locks in item 1 first because of its higher ratio and then has no room left for item 2 - it is not the true 0/1 optimum.
Why C tempts people
Weight 5 plus 10 is 15, which exceeds the capacity of 10, so both items together are not a valid choice.
Why D tempts people
Item 2 alone weighs exactly 10, which fits the capacity of 10 - it is a fully valid, and in fact optimal, choice worth 50.

121. Answer it before you see the options: Check yourself: minimum coins

Prediction

Predict first

What is the fewest coins needed to make amount 5?

Answer it in your own words, now, with nothing to choose from. The options are on the next slide — and picking the right one off a list is an easier skill than producing it.

Correct: 2, using a 4 and a 1.

Why: The amount-5 entry equals the minimum of trying each coin last: 1 plus the amount-4 entry, 1 plus the amount-2 entry, or 1 plus the amount-1 entry, which works out to 2, 3, and 2. The minimum, 2, is achieved by combining a 4 and a 1, which sum to 5.

122. Check yourself: minimum coins

Check

Coins available: 1, 3, and 4, in unlimited supply.

Check your understanding

What is the fewest coins needed to make amount 5?

  • A. 2, using a 4 and a 1. (correct)
  • B. 5, using five 1's.
  • C. 3, using a 3, a 1, and a 1.
  • D. 1, using a single coin of value 5.

Answer: A

Why: The amount-5 entry equals the minimum of trying each coin last: 1 plus the amount-4 entry, 1 plus the amount-2 entry, or 1 plus the amount-1 entry, which works out to 2, 3, and 2. The minimum, 2, is achieved by combining a 4 and a 1, which sum to 5.

Why B tempts people
This uses only 1's without ever trying the larger coins 3 or 4, which reach the same amount in fewer coins.
Why C tempts people
This combination does sum to 5, but it uses one more coin than necessary - 3 plus 1 plus 1 uses 3 coins where 4 plus 1 uses only 2.
Why D tempts people
There is no coin of value 5 in this coin system - only 1, 3, and 4 are available, so a single coin cannot make 5.

123. How sure are you: Check yourself: counting ways

Commit first

Predict first

How many distinct combinations of coins worth 1 and 2 sum to exactly 3?

Commit to an answer, then rate it — certain, fairly sure, or guessing — and write the rating down before you turn the page.

Correct: 2, the combinations of three 1's, and one 1 with one 2.

Why: There are exactly two combinations of 1's and 2's that sum to 3: three 1's, or one 1 plus one 2. Order doesn't matter, so listing the 1 first or the 2 first counts as the same combination, matching the table's entry of 2 for amount 3.

The rating matters as much as the answer: confident-and-wrong is the combination that survives revision, because nothing about it feels like it needs revisiting.

124. Check yourself: counting ways

Check

Coin types available: value 1 and value 2, in unlimited supply.

Check your understanding

How many distinct combinations of coins worth 1 and 2 sum to exactly 3?

  • A. 2, the combinations of three 1's, and one 1 with one 2. (correct)
  • B. 3, treating a 1 followed by a 2 as different from a 2 followed by a 1.
  • C. 1, only three 1's.
  • D. 0, since 3 is odd and 2 is even.

Answer: A

Why: There are exactly two combinations of 1's and 2's that sum to 3: three 1's, or one 1 plus one 2. Order doesn't matter, so listing the 1 first or the 2 first counts as the same combination, matching the table's entry of 2 for amount 3.

Why B tempts people
This counts the two orderings of one 1 and one 2 as separate combinations, but this problem counts combinations, not ordered sequences - they use the identical collection of coins.
Why C tempts people
This misses the combination of one 1 plus one 2, which is a valid way to make 3 using one coin of each denomination.
Why D tempts people
Coins don't need to individually be odd or even to sum to an odd amount - one coin of value 1, which is odd, plus one of value 2, which is even, sums to 3, which is odd.

125. Answer it before you see the options: Check yourself: rod cutting

Prediction

Predict first

What is the best obtainable revenue for a rod of length 4, and how is it achieved?

Answer it in your own words, now, with nothing to choose from. The options are on the next slide — and picking the right one off a list is an easier skill than producing it.

Correct: 10, by cutting a first piece of length 2 and using the best revenue for the remaining length-2 rod.

Why: The length-4 entry is the maximum over every first-cut length: 1 plus the length-3 entry, 5 plus the length-2 entry, 8 plus the length-1 entry, or 9 plus the length-0 entry, giving 9, 10, 9, and 9. The maximum, 10, comes from a first cut of length 2 combined with the best revenue from the remaining length-2 rod, which is itself a single piece of length 2.

126. Check yourself: rod cutting

Check

Price list: lengths 1 through 5 sell for 1, 5, 8, 9, and 10. Consider a rod of length 4.

length12345
price158910

Check your understanding

What is the best obtainable revenue for a rod of length 4, and how is it achieved?

  • A. 10, by cutting a first piece of length 2 and using the best revenue for the remaining length-2 rod. (correct)
  • B. 9, by selling the rod whole at length 4.
  • C. 11, by cutting into four pieces of length 1.
  • D. 13, by cutting a first piece of length 2 and a first piece of length 3.

Answer: A

Why: The length-4 entry is the maximum over every first-cut length: 1 plus the length-3 entry, 5 plus the length-2 entry, 8 plus the length-1 entry, or 9 plus the length-0 entry, giving 9, 10, 9, and 9. The maximum, 10, comes from a first cut of length 2 combined with the best revenue from the remaining length-2 rod, which is itself a single piece of length 2.

Why B tempts people
Selling the rod whole at length 4 earns its listed price of 9, which is one option the recurrence checks, but it is not the best one available.
Why C tempts people
Four pieces of length 1 earn 1 plus 1 plus 1 plus 1, or 4 total, far below the 10 found using a length-2 first cut.
Why D tempts people
13 is the optimal revenue for a rod of length 5, not length 4 - cutting into length 2 and length 3 needs a rod of length 5, one unit longer than the rod in this question.

127. Rule out three: Check yourself: sizing a table correctly

Elimination

Eliminate the wrong options

How many entries should the table have, from the smallest amount up to the target?

3 of these 4 are wrong. Strike them one at a time, and say what rules each one out before you strike the next. The survivor is the answer.

  • A. 9 entries, for amounts 0 through 8.
  • B. 8 entries, for amounts 0 through 7.
  • C. 8 entries, for amounts 1 through 8.
  • D. 7 entries, for amounts 1 through 7.

Survives elimination: A

Why: The table must hold one entry for every amount from 0 up to and including the target, 8. That is 8 minus 0 plus 1, or 9 entries. Leaving out amount 0 or amount 8 removes either the base case or the final answer itself.

128. Check yourself: sizing a table correctly

Check

You are filling a minimum-coins table for a target amount of 8.

Check your understanding

How many entries should the table have, from the smallest amount up to the target?

  • A. 9 entries, for amounts 0 through 8. (correct)
  • B. 8 entries, for amounts 0 through 7.
  • C. 8 entries, for amounts 1 through 8.
  • D. 7 entries, for amounts 1 through 7.

Answer: A

Why: The table must hold one entry for every amount from 0 up to and including the target, 8. That is 8 minus 0 plus 1, or 9 entries. Leaving out amount 0 or amount 8 removes either the base case or the final answer itself.

Why B tempts people
This range stops at amount 7, one short of the target - the same off-by-one mistake as sizing a knapsack table with only 'capacity' columns instead of 'capacity plus one'.
Why C tempts people
This range leaves out amount 0, which is the base case the whole recurrence depends on - without it there is nothing to build amount 1 from.
Why D tempts people
This range leaves out both amount 0, the base case, and amount 8, the actual target, so neither the starting fact nor the final answer would exist in the table.

129. Toolkit update

Concept

Moves added today: none.

That is a result, not a gap. Everything in this lesson was proved with moves you already owned.

Moves you reused today:

Three different problems today, one procedure. The only thing that changed between knapsack, coin change and rod cutting was the sentence in step 1 and the last decision in step 2.

Full toolkit so far: #1 through #13.

Next session opens with you naming every one of these from memory, before any new material.

130. Break it if you can: Toolkit update

Counterexample

Discussion prompt

Three different problems today, one procedure. The only thing that changed between knapsack, coin change and rod cutting was the sentence in step 1 and the last decision in step 2.

That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.

Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.

Answer:

Next session opens with you naming every one of these from memory, before any new material.

131. Why greedy fails on 0/1 knapsack

Picture it

Animation

Shows: Why greedy fails on 0/1 knapsack — a rendered Manim animation.

Rendered with Manim.

Takeaway: The best ratio is not the best set.

132. Connect it up: Dynamic Programming II: Knapsack, Coin Change & Rod Cutting

Connect it up

Draw it

One page, no notation unless you need it: draw how these connect — The five-step DP setup recipe · Toolkit check-in: name them before you look · Two ingredients every DP needs · The 0/1 knapsack problem · Why it's called 0/1. Put an arrow wherever one of them is what makes another possible, and label the arrow with why.

133. What you can do now

Recap

You now have the setup habit that makes any new DP problem tractable: define the state in words, write the recurrence as an explicit choice, pin down the base case, fill in dependency order, and plan the reconstruction from the start.

TechniqueThe one move
0/1 knapsackmax of skip vs. take, row above only
Minimum coinsmin over every coin tried last
Counting wayssum of without-this-coin and with-this-coin
Rod cuttingmax over every possible first-cut length

Sources

  1. Cormen, Leiserson, Rivest, and Stein, Introduction to Algorithms, 3rd ed., Chapter 15 (Dynamic Programming: rod cutting; exercises cover 0/1 knapsack) — MIT Press, 2009.
  2. Kleinberg and Tardos, Algorithm Design, Chapter 6 (Dynamic Programming) — Pearson/Addison-Wesley, 2005.
  3. All recurrences, table traces, reconstructions, and complexity claims in this deck were recomputed by hand and cross-checked against brute-force enumeration for every worked example. — Verified 2026-07-18.
  4. Northeastern University CS 3000, Algorithms and Data (Summer 2026) — course page and syllabus — course.ccs.neu.edu/cs3000su26. Sets Cormen, Leiserson, Rivest and Stein, Introduction to Algorithms (3rd ed.) as the textbook; listings follow its conventions.
  5. CS 3000 course notes and midterm references circulated by students — github.com/vigneshsaravanakumar404/CS-3000-Algorithms-Data. Notes are typeset with the algpseudocode package, which is the style the listings in this deck follow.

Want this taught 1-on-1? Alexander tutors CS3000 Algorithms — $55/session, free consultation.

Book on Wyzant · Text (657) 465-8108