PrepStack · Markdown HTML

0/1 or unbounded knapsack DP

Dynamic programming · HTML

Formal shape

dp[c] describes capacity/sum c. For 0/1 items (w,v), iterate c from C down to w and set dp[c]=Agg(dp[c],dp[c-w]⊕v). For unbounded use, iterate c upward.

Recognition signals

False friends

SignalWhy it is different
Huge capacity with few itemsO(nC) is infeasible; consider meet-in-the-middle, sparse reachable sets, or DP by value.
Order is part of the outcomeItem-outer loops deduplicate combination order; ordered sequence counting needs a different loop structure.
Greedy value densityDensity is valid for divisible items, not indivisible 0/1 choices.

Core invariant

After the first i item types, dp[c] contains exactly the allowed answers using those types. Descending 0/1 capacity prevents the current item from reading its own update.

State, transition, and processing order

ItemDefinition
StateFeasibility, optimum, or count for capacity/sum c, with False, -infinity, or infinity for unreachable states.
TransitionCombine skipping at old dp[c] with taking the item from dp[c-w]. Direction decides whether dp[c-w] belongs to the previous item layer or current layer.
Frontier / orderItem layers advance forward; capacity runs backward for 0/1 and forward for unbounded reuse.

Python skeleton

def zero_one_max_value(items, capacity):
    dp = [0] * (capacity + 1)
    for weight, value in items:
        for c in range(capacity, weight - 1, -1):
            dp[c] = max(dp[c], dp[c - weight] + value)
    return dp[capacity]

Correctness sketch

  1. Initially, choosing no items satisfies the base interpretation.
  2. For item i, any optimum either skips it and keeps old dp[c], or takes it and extends a solution at c-w that excludes i.
  3. Descending capacity keeps c-w on the prior layer, enforcing at-most-once use; induction gives the 0/1 optimum.

Complexity

TimeSpaceParameters
O(nC)O(C) compressedn is item count and C the numeric capacity/target; the bound is pseudo-polynomial.

Edge cases

Error patterns

PatternWhy it fails / fix
Ascending capacity for 0/1It reads dp[c-w] updated by the same item and silently becomes unbounded knapsack.
Confusing combinations and permutationsItem-outer loops usually count unordered combinations; capacity-outer loops may count different orders separately.
Initializing unreachable states to zeroFor exact-capacity maximization, nonexistent constructions become falsely feasible; use negative infinity.
Ignoring pseudo-polynomial scaleRuntime depends on numeric C rather than its bit length and can be enormous.

Selection and exclusion rules

RelationTemplateBoundary
contrastSubset / combination backtrackingActual constructions must be enumerated rather than aggregated.

Original micro-example

PartDetail
ResultThe 0/1 optimum is 9; ascending updates could illegally reuse (2,4).
SetupCapacity is 5; items are (2,4), (3,5), and (4,7).
TraceThe first two exactly fill capacity with value 9; the third alone yields 7.

Recall prompts

My notes