unbounded knapsack Suppose I have infinite copies of all items, what’s the most valuable way to fill the knapsack? DP, with subproblems containing smaller knapsack. K[x] = max_i { K[x-wi] + vi } def solve(): dp[0] = 0 sol[0] = [] for x in 1 ... knapsack_size: dp[x] = 0 for i in 1 ... num_items: if weight(i) <= x: # why max base case instead of incrementally adding stuff? # a bigger knapsack that fits 2 things can be find a sa dp[x] = max(dp[x], dp[x-weight(i)]+value(i)) if dp[x] changed: sol[x] = sol[x-weight(i)] + [i] 0/1 knapsack Suppose I have one copy of each item; what’s the most valuable way to fill the knapsack? We have to keep track of a 2D DP table. Casework: optimal solution for j items doesn’t use item j: K[x,j] = K[x,j-1] optimal solution for j items does use item j: K[x,j] = K[x-weight(j),j-1]+value(j) So we have: K[x,j] = max(K[x,j-1], K[x-weight(j),j-1]+value(j), for each j). We can thus solve 0/1 knapsack in O\left(nW\right).