Mr. Latte


Lesson 7 of 16

Take It or Leave It: Knapsack

Maximize the total value in a bag without exceeding its weight limit. Items cannot be split, and each may be used once. This is 0/1 knapsack: exclude an item or include it.

What changes from the coin problem?

The coin lesson allowed unlimited copies of a denomination. Here, reusing an item is invalid. Define a state as the best value achievable with capacity w using only the first i items.

Reduce the table to one row

items = [(2, 5), (3, 7), (4, 9)]
capacity = 5
dp = [0] * (capacity + 1)
for weight, value in items:
    for space in range(capacity, weight - 1, -1):
        dp[space] = max(dp[space], dp[space - weight] + value)
print(dp[capacity])

Items are (weight, value) pairs. The result is 12, using weights 2 and 3. Update from larger capacities down to smaller ones so dp[space-weight] still excludes the current item.

If capacities increase instead, an item of weight 2 can first update capacity 2, then be reused when capacity 4 reads that newly updated result.

What does “efficient” mean here?

For n items and integer capacity W, time is O(nW) and space is O(W). Large W is expensive. Representing W in the input needs far fewer digits, so this is not a polynomial-time solution in the full encoded input length. It is pseudo-polynomial.

If items can be split, the fractional knapsack problem permits a greedy method ordered by value per unit weight. That is a different set of conditions from 0/1 knapsack.

Check your understanding

There is one item (2, 5) and capacity 4. If a program returns 10, which rule did it violate?

Show explanation

It used the item twice. The 0/1 answer is 5. Updating capacities upward can reuse the current item, so check the loop direction.

Looking for a product partner? Founders, teams, businesses: from problem framing to launch.