Exercises — When greedy fails — 0 - 1 knapsack counter-example
Before we start, one reminder drawn as a picture, because every exercise leans on it:

Recall What the picture says
The bag is a fixed-width box of capacity . Greedy fills from the left with the densest items first (tall amber bars = high value-per-width). When the next dense item is wider than the leftover slot, greedy skips it and the slot stays empty — that empty slot (the amber-outlined gap) is exactly the value greedy throws away.
Level 1 — Recognition
Exercise 1.1
State, in one sentence each, the two structural properties a problem must have for a greedy algorithm to be provably optimal.
Recall Solution
- Greedy-choice property — some globally optimal solution contains the locally best (greedy) choice, so committing to it never rules out reaching an optimum. (See Greedy-Choice Property.)
- Optimal substructure — the optimal solution of the whole problem is built from optimal solutions of subproblems (see Optimal Substructure). Both are typically proven by an Exchange Argument. 0/1 knapsack has optimal substructure but lacks the greedy-choice property, which is why greedy fails.
Exercise 1.2
For the parent's items — A, B, C — compute each density and write the greedy sort order.
Recall Solution
Descending order: . This is the order greedy walks the list in.
Level 2 — Application
Exercise 2.1
Run density-greedy on the parent instance (). Report the chosen set, total value, and the wasted capacity.
Recall Solution
Walk with remaining capacity , start :
- Take A (needs 10 ≤ 50): value , .
- Take B (needs 20 ≤ 40): value , .
- Try C (needs 30 > 20): doesn't fit, skip. Chosen , total value , wasted capacity .
Exercise 2.2
Now enumerate every feasible subset for and find the true optimum. Confirm greedy is not optimal.
Recall Solution
All subsets, weight then value (feasible = weight ≤ 50):
| Subset | weight | value | feasible? |
|---|---|---|---|
| 0 | 0 | ✓ | |
| A | 10 | 60 | ✓ |
| B | 20 | 100 | ✓ |
| C | 30 | 120 | ✓ |
| A,B | 30 | 160 | ✓ |
| A,C | 40 | 180 | ✓ |
| B,C | 50 | 220 | ✓ |
| A,B,C | 60 | — | ✗ (over 50) |
Optimum . Greedy got , so greedy is not optimal here. (This is the Fractional Knapsack–vs–0/1 contrast: only 0/1 can strand capacity.)
Level 3 — Analysis
Exercise 3.1
Fill the DP table for the parent instance, but only for the capacities you actually need: . Read off .
Recall Solution
Recurrence: if , else . Base row .
Why these two cases exhaust everything: for item there are only two possible fates — it is either in the chosen set or out. That is a complete, non-overlapping split of all solutions.
- Out (skip): if is not chosen, the best we can do is the best over the remaining items with the same capacity — that is exactly .
- In (take): if is chosen, it consumes of capacity and contributes ; whatever is packed alongside it must be an optimal pack of items in the reduced capacity — that is , and it is only legal when . Because "in" and "out" cover all possibilities, taking the of the two is guaranteed to be the true best — and the fact that each branch re-uses an optimal smaller answer is precisely Optimal Substructure. This is why DP never commits early: it evaluates both fates instead of guessing one.
Order items A, B, C.
| 0 | 10 | 20 | 30 | 40 | 50 | |
|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | |
| (A) | 0 | 60 | 60 | 60 | 60 | 60 |
| (B) | 0 | 60 | 100 | 160 | 160 | 160 |
| (C) | 0 | 60 | 100 | 160 | 180 | 220 |
Sample step, : skip C → ; take C → . Max is . ✓ matches B+C.
Exercise 3.2
Point to the exact cell in the table where DP beats greedy, and explain why greedy could not reach it.
Recall Solution
The cell (and its parent , meaning "use B in a size-20 slot"). DP considered the branch "skip A entirely" — that is what leaves room for both B (20) and C (30) to sum to exactly 50. Greedy committed to A first (highest density) and could never un-commit, so it never explored the "skip A" universe. This is the Optimal Substructure paying off: DP keeps the best answer for every capacity, including capacities that only make sense if you skip a dense item.
Level 4 — Synthesis
Exercise 4.1
Build a new 3-item instance where density-greedy achieves less than half the optimum. Prove your numbers.
Recall Solution
Capacity . Items (listed X, Y, Z — this order also fixes tie-breaks):
- X: , , (densest, but tiny).
- Y: , , .
- Z: , , .
Greedy: takes X first (density 2.0) → . Now Y and Z each need weight 100, but only 99 units remain, so neither fits. Greedy value . Optimum: take Y alone (or Z alone), weight , value . So greedy , optimum . Ratio — density-greedy is here 50× worse. The mechanism is exactly the parent's warning: X's single unit of weight drops the remaining capacity from 100 to 99, which is just enough to lock out the heavy 100-value items. Pushing X's value toward keeps the same blocking effect and drives the ratio → 0, showing density-greedy can be arbitrarily bad.
Exercise 4.2
State the guaranteed cheap heuristic from the parent and apply it to your Exercise 4.1 instance. Show it now hits the ½-bound.
Recall Solution
Heuristic: return .
- Density-greedy value (from 4.1).
- Best single item that fits in : Y or Z, value .
- . Optimum is , so the heuristic returns . ✓ It meets the ½-approximation guarantee (see Approximation Algorithms). The "best single item" clause is what rescues the case where one heavy item is the whole answer.
Level 5 — Mastery
Exercise 5.1
The DP runs in . Explain precisely why this is not proof that 0/1 knapsack is "easy" (polynomial-time in the usual sense), linking to the right vault concept.
Recall Solution
is pseudo-polynomial: it is polynomial in the numeric value , not in the number of bits needed to write . Writing takes bits, so — the runtime is exponential in the input length. If we let (and weights) grow like , the table has cells and DP is intractable. 0/1 knapsack is in fact NP-hard; no known algorithm is polynomial in the bit-length of the input. So is a genuine, useful bound only when is small.
Exercise 5.2
Recall the Exchange Argument that proves greedy optimal for Fractional Knapsack. Pinpoint the single line that becomes illegal in 0/1, and explain the consequence in your own words.
Recall Solution
Definition of the sliver. Let be an arbitrarily small positive weight increment, i.e. we consider the limit , and we always remove exactly the same amount that we add, so the swap is weight-preserving by construction. Fractional exchange: given an optimal solution missing some of the densest available item , take a sliver of mass of and remove an equal mass of a lower-density item. Total weight is unchanged (we added and removed ), and value strictly rises (higher density in, lower density out) — a contradiction unless the optimum already used all of it could. The illegal line in 0/1: "take a sliver of mass ." In 0/1 the only allowed swap is a whole item, so can no longer shrink toward 0 — it jumps to a full weight . That whole swap changes total weight and may violate — the exchange is not guaranteed feasible. Consequence: with no feasible weight-preserving exchange, there is no proof that a greedy choice is safe, so greedy-optimality collapses and we fall back to Dynamic Programming.
Exercise 5.3 (capstone)
Design an instance with 4 items where (a) density-greedy fails, (b) value-greedy also fails, but they fail by choosing different sets. Give both greedy answers and the true optimum.
Recall Solution
. Items listed P, Q, R, S (listing order also fixes ties, per the page-wide rule):
- P: , ()
- Q: , ()
- R: , ()
- S: , ()
Note R and S tie at ; the tie-breaking rule considers R before S (R is listed first). (a) Density-greedy order : take P (), take Q (), R needs 30 skip, S needs 50 skip → set , value . (b) Value-greedy (sort by value: S R Q P): take S (, ) → nothing else fits → set , value . True optimum: enumerate feasible sets ≤ 50. Candidates: , (wt 50), , (wt 40). Best is . So density-greedy → (set ), value-greedy → (set ) — different wrong sets — and the optimum is set , chosen by neither heuristic. This is the sharpest form of the parent's lesson: no single sort key finds the optimum.
Recall One-line summary of the whole page
Greedy (by any key) can strand capacity or hog it; the fix is DP with , giving the true optimum on the parent instance and correctly handling every instance you built here.
Connections
- When greedy fails — 0 - 1 knapsack counter-example (index 3.7.5) — the parent topic
- 3.7.05 When greedy fails — 0 - 1 knapsack counter-example (Hinglish) — Hinglish version
- Greedy Algorithms · Fractional Knapsack · Dynamic Programming
- Optimal Substructure · Greedy-Choice Property · Exchange Argument
- NP-hardness · Approximation Algorithms