Knapsack Problems

Back

Loading concept...

The Treasure Hunterโ€™s Guide to Knapsack Problems ๐ŸŽ’

Imagine youโ€™re a treasure hunter with a magical backpack. The backpack can only hold a certain weight, but every treasure has a different weight and value. How do you pick the BEST treasures to carry home?


What Are Knapsack Problems?

Think of your school bag. It can only hold so much stuff before it gets too heavy. Now imagine you have:

  • A heavy math book (worth a lot for your grades)
  • A light notebook (worth less but easy to carry)
  • A medium lunchbox (super important!)

The Question: Which items do you pick to get the MOST value without breaking your bag?

This is the Knapsack Problem โ€” one of the most famous puzzles in computer science!

graph TD A["๐ŸŽ’ Your Bag<br>Limited Space"] --> B{What to pick?} B --> C["๐Ÿ’Ž Heavy Gold<br>High Value"] B --> D["๐Ÿ’ Light Ring<br>Medium Value"] B --> E["๐Ÿ“ฟ Medium Gem<br>Good Value"]

The Three Types of Knapsack Problems

Type Rule Real Life Example
0-1 Knapsack Take it OR leave it Packing for vacation
Unbounded Take as many as you want Buying snacks
Coin Change Make exact amount Paying with coins

1. The 0-1 Knapsack Problem

The Story

Youโ€™re at a treasure cave. Each treasure can ONLY be picked ONCE โ€” you either take it (1) or leave it (0). Thatโ€™s why itโ€™s called โ€œ0-1โ€!

Simple Example

Your bag capacity: 7 kg

Treasure Weight Value
Crown ๐Ÿ‘‘ 3 kg $4
Necklace ๐Ÿ“ฟ 4 kg $5
Ring ๐Ÿ’ 2 kg $3

Question: Whatโ€™s the maximum value you can carry?

Answer: Take Crown (3kg, $4) + Necklace (4kg, $5) = 7kg total, $9 value!

Or: Crown (3kg, $4) + Ring (2kg, $3) = 5kg, $7 valueโ€ฆ Not as good!


How Does It Work? (The DP Table Magic)

We build a table that answers: โ€œIf I had X kg capacity and could choose from first Y items, whatโ€™s the best value?โ€

The Magic Formula

For each item, we ask two questions:

  1. Skip it: Keep the best value we had before
  2. Take it: Add this itemโ€™s value to what we could fit before

Pick whichever is bigger!

// For each item and capacity
if (item weight <= current capacity) {
  best = max(
    skip it,
    take it + remaining space value
  )
}

Building the Table

Capacity โ†’    0   1   2   3   4   5   6   7
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
No items      0   0   0   0   0   0   0   0
+Crown(3,$4)  0   0   0   4   4   4   4   4
+Necklace     0   0   0   4   5   5   5   9
+Ring         0   0   3   4   5   7   8   9
                                        โ†‘
                              Answer: $9!

The Code (Simple Version)

function knapsack01(W, weights, values) {
  const n = weights.length;
  const dp = Array(n + 1).fill(null)
    .map(() => Array(W + 1).fill(0));

  for (let i = 1; i <= n; i++) {
    for (let w = 0; w <= W; w++) {
      // Option 1: Don't take item
      dp[i][w] = dp[i-1][w];

      // Option 2: Take item (if it fits)
      if (weights[i-1] <= w) {
        const takeIt = values[i-1]
          + dp[i-1][w - weights[i-1]];
        dp[i][w] = Math.max(dp[i][w], takeIt);
      }
    }
  }
  return dp[n][W];
}

2. The Unbounded Knapsack Problem

The Story

Now imagine a candy store where you can buy AS MANY of each candy as you want! The shelf never runs out. How do you fill your bag with maximum yumminess?

Key Difference from 0-1

0-1 Knapsack Unbounded Knapsack
Take each item at most ONCE Take any item INFINITE times
Like unique treasures Like items in a store

Simple Example

Your bag capacity: 8 kg

Item Weight Value
Apple ๐ŸŽ 2 kg $3
Orange ๐ŸŠ 3 kg $4
Watermelon ๐Ÿ‰ 5 kg $7

Question: Whatโ€™s the maximum value?

Think: We can take multiple apples! 4 Apples = 8kg, $12

Or: 1 Watermelon + 1 Orange = 8kg, $11

Best Answer: 4 Apples = $12!


The Magic Formula

Instead of looking at the โ€œprevious rowโ€ (without this item), we look at the โ€œcurrent rowโ€ (where we might have already taken this item):

graph TD A["Can I fit this item?"] -->|Yes| B["Two choices"] B --> C["Skip: keep dp of w"] B --> D["Take: value + dp of w-weight"] C --> E["Pick the MAX"] D --> E A -->|No| F["Keep previous best"]

The Code

function unboundedKnapsack(W, weights, values) {
  const n = weights.length;
  const dp = Array(W + 1).fill(0);

  for (let w = 1; w <= W; w++) {
    for (let i = 0; i < n; i++) {
      if (weights[i] <= w) {
        // Can keep adding same item!
        dp[w] = Math.max(
          dp[w],
          values[i] + dp[w - weights[i]]
        );
      }
    }
  }
  return dp[W];
}

Notice: We use dp[w - weights[i]] from the SAME array (not previous row), allowing infinite copies!


3. The Coin Change Problem

The Story

Youโ€™re at a vending machine. A snack costs exactly $11. You have unlimited coins of $1, $3, and $5. Whatโ€™s the FEWEST coins needed?

Two Versions

Version Question
Minimum Coins Fewest coins to make amount
Count Ways How many different ways exist?

Version 1: Minimum Coins

Target: $11 Coins: $1, $3, $5

Building the Solution

For each amount (0 to 11), find minimum coins needed:

Amount:  0  1  2  3  4  5  6  7  8  9  10  11
Coins:   0  1  2  1  2  1  2  3  2  3   2   3

How?

  • Amount 3: Use one $3 coin โ†’ 1 coin
  • Amount 5: Use one $5 coin โ†’ 1 coin
  • Amount 11: Use $5+$5+$1 โ†’ 3 coins โœ“
graph TD A["$11 target"] --> B["Try $1"] A --> C["Try $3"] A --> D["Try $5"] B --> E["$10 + 1 coin"] C --> F["$8 + 1 coin"] D --> G["$6 + 1 coin"] G --> H["Best: 3 coins total"]

The Code (Minimum Coins)

function minCoins(coins, amount) {
  const dp = Array(amount + 1).fill(Infinity);
  dp[0] = 0; // 0 coins for $0

  for (let a = 1; a <= amount; a++) {
    for (const coin of coins) {
      if (coin <= a && dp[a - coin] !== Infinity) {
        dp[a] = Math.min(dp[a], 1 + dp[a - coin]);
      }
    }
  }

  return dp[amount] === Infinity ? -1 : dp[amount];
}

// Example: minCoins([1,3,5], 11) โ†’ 3

Version 2: Count Ways

Question: How many different ways to make $5 using $1 and $2 coins?

All the Ways

  1. $1 + $1 + $1 + $1 + $1 (five $1s)
  2. $1 + $1 + $1 + $2 (three $1s + one $2)
  3. $1 + $2 + $2 (one $1 + two $2s)

Answer: 3 ways!

The Code (Count Ways)

function countWays(coins, amount) {
  const dp = Array(amount + 1).fill(0);
  dp[0] = 1; // One way to make $0

  for (const coin of coins) {
    for (let a = coin; a <= amount; a++) {
      dp[a] += dp[a - coin];
    }
  }

  return dp[amount];
}

// Example: countWays([1,2], 5) โ†’ 3

The Big Picture

graph LR A["๐ŸŽ’ Knapsack Family"] --> B["0-1 Knapsack"] A --> C["Unbounded Knapsack"] A --> D["Coin Change"] B --> B1["Each item once"] B --> B2["Maximize value"] C --> C1["Unlimited copies"] C --> C2["Maximize value"] D --> D1["Unlimited coins"] D --> D2["Min coins OR count ways"]

Quick Comparison

Problem Items Per Type Goal
0-1 Knapsack At most 1 Max value in capacity
Unbounded Unlimited Max value in capacity
Coin Change Unlimited Min coins OR count ways

Why This Matters

These problems appear EVERYWHERE:

  • Video Games: Best items for inventory slots
  • Shopping: Best items within budget
  • Investing: Best stocks within money limit
  • Packing: Best items for luggage weight

Remember This!

Dynamic Programming = Breaking big problems into smaller ones, saving answers so we donโ€™t repeat work!

Every knapsack problem asks: โ€œFor each capacity, whatโ€™s the best I can do?โ€

We build up from small capacities to big ones, using our previous answers.

Thatโ€™s the magic! โœจ


Youโ€™re now a Knapsack Problem treasure hunter! Go optimize those bags! ๐ŸŽ’๐Ÿ’Ž

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.