Menu

Earn Premium with Referrals

Invite your friends and earn Premium rewards through our referral program.

See how it works and start inviting friends.

Fractional Knapsack
DSA

Fractional Knapsack

Understand how value-to-weight ratios lead to an optimal greedy solution for fractional knapsack.

Fractional Knapsack maximizes total value when you can take fractions of items.

Ratio sort → full takes → one fractional cut → stop. Watch the bag fill:

Fractional Knapsack

Maximize value in a capacity-limited bag when items can be split.

Sort items by value/weight ratio and take them in that order: whole if they fit, or the fraction that fills the bag. Because items are divisible, greedy by ratio is optimal and you can stop as soon as the bag is full. (0/1 knapsack can't cut items, so greedy fails there.)

ARRAY VISUALIZER
Steps
r=4.0
0
r=3.0
1
r=1.5
2
r=1.0
3
Press ▶ to animate, or step through manually.
Variables
keys: ← → space F
Pseudocode

                        1
                        sort items by value/weight ratio, descending
                      
                        2
                        for each item:
                      
                        3
                          if it fits fully: take all of it
                      
                        4
                          else: take the fraction that fills the bag
                      
                        5
                          stop when bag is full
                      

The key idea is:

Always take the item with the highest value per unit of weight first.

Focus on recognizing:

“Maximum value” + “Weight capacity” + “Fractions allowed” = Fractional Knapsack


Pattern Table

PatternTypical QuestionsTrigger
Fractional KnapsackMaximum value under capacitySort by value/weight
0/1 KnapsackTake whole items onlyDynamic Programming

Mental Trigger

Calculate value/weight → Sort descending → Take as much as possible


1. Generic Fractional Knapsack Template (Base)

This is the main template to remember.

class Item {
    int value;
    int weight;

    Item(int value, int weight) {
        this.value = value;
        this.weight = weight;
    }
}

public double fractionalKnapsack(int capacity, Item[] items) {

    Arrays.sort(items, (a, b) -> {
        double r1 = (double) a.value / a.weight;
        double r2 = (double) b.value / b.weight;

        return Double.compare(r2, r1);
    });

    double totalValue = 0;

    for (Item item : items) {

        // Take the whole item
        if (item.weight <= capacity) {

            totalValue += item.value;
            capacity -= item.weight;

        } else {

            // Take only the fraction that fits
            totalValue += (double) item.value
                    * capacity / item.weight;

            break;
        }
    }

    return totalValue;
}
class Item:
    def __init__(self, value, weight):
        self.value = value
        self.weight = weight

def fractional_knapsack(capacity, items):
    items.sort(
        key=lambda item: item.value / item.weight,
        reverse=True,
    )

    total_value = 0

    for item in items:

        # Take the whole item
        if item.weight <= capacity:
            total_value += item.value
            capacity -= item.weight

        else:
            # Take only the fraction that fits
            total_value += item.value * capacity / item.weight

            break

    return total_value
struct Item {
    int value;
    int weight;

    Item(int v, int w) : value(v), weight(w) {}
};

double fractionalKnapsack(int capacity, vector<Item>& items) {
    sort(items.begin(), items.end(),
         [](const Item& a, const Item& b) {
             double r1 = (double)a.value / a.weight;
             double r2 = (double)b.value / b.weight;

             return r1 > r2;
         });

    double totalValue = 0;

    for (Item& item : items) {

        // Take the whole item
        if (item.weight <= capacity) {
            totalValue += item.value;
            capacity -= item.weight;

        } else {
            // Take only the fraction that fits
            totalValue += (double)item.value * capacity / item.weight;

            break;
        }
    }

    return totalValue;
}
class Item {
  constructor(value, weight) {
    this.value = value;
    this.weight = weight;
  }
}

function fractionalKnapsack(capacity, items) {
  items.sort(
    (a, b) => b.value / b.weight - a.value / a.weight
  );

  let totalValue = 0;

  for (const item of items) {
    // Take the whole item
    if (item.weight <= capacity) {
      totalValue += item.value;
      capacity -= item.weight;
    } else {
      // Take only the fraction that fits
      totalValue += (item.value * capacity) / item.weight;

      break;
    }
  }

  return totalValue;
}

How it works

Suppose:

Capacity = 50

Item       Value    Weight
A           60       10
B          100       20
C          120       30

Calculate value/weight:

A → 60 / 10 = 6
B → 100 / 20 = 5
C → 120 / 30 = 4

Take in this order:

A → whole item
B → whole item
C → only the remaining fraction

Pattern 1: Sort by Value/Weight Ratio

This is the most important part of Fractional Knapsack.

What Changed from the Base?

This is the base pattern itself.

Calculate:

double ratio = (double) item.value / item.weight;

Then sort from highest to lowest:

Arrays.sort(items, (a, b) -> {
    double r1 = (double) a.value / a.weight;
    double r2 = (double) b.value / b.weight;

    return Double.compare(r2, r1);
});

Why?

Because an item with a higher value per unit of weight gives us more value for every unit of capacity.

Fractional Knapsack = Greedy by value/weight ratio.


Pattern 2: Take the Whole Item

After sorting, check whether the entire item fits.

What Changed from the Base?

Use:

if (item.weight <= capacity)

If it fits:

totalValue += item.value;
capacity -= item.weight;

We take the entire item.

If the item fits → Take all of it.


Pattern 3: Take a Fraction

If the complete item does not fit, take only the portion that fits.

What Changed from the Base?

Instead of adding the complete value:

totalValue += item.value;

calculate the fraction:

totalValue += (double) item.value
        * capacity / item.weight;

For example:

Item value  = 100
Item weight = 20
Remaining capacity = 5

We can take:

5 / 20 = 25%

So the value is:

100 × 5 / 20 = 25

If the item does not fit → Take the fraction that fills the remaining capacity.


Pattern 4: Stop After Taking a Fraction

Once we take a fraction, the capacity is completely full.

What Changed from the Base?

Add:

break;

after taking the fraction:

totalValue += (double) item.value
        * capacity / item.weight;

break;

There is no capacity left for another item.

First fractional item → Capacity is full → Stop.


Fractional Knapsack Pattern Evolution

Base

Calculate value / weight

Sort descending

Take whole item if it fits

Otherwise take fraction

Capacity full → Stop

Common Mistakes

1. Using Integer Division

Wrong:

double ratio = item.value / item.weight;

This performs integer division first.

Correct:

double ratio =
        (double) item.value / item.weight;

2. Sorting in the Wrong Direction

Wrong:

Double.compare(r1, r2);

Correct:

Double.compare(r2, r1);

We want the highest value/weight ratio first.


3. Treating Fractional Knapsack Like 0/1 Knapsack

Fractional Knapsack allows:

Take 100%
Take 50%
Take 25%
...

0/1 Knapsack allows only:

Take 100%
or
Take 0%

Therefore:

Fractional Knapsack → Greedy

0/1 Knapsack → Dynamic Programming


4. Forgetting to Stop After a Fraction

After:

totalValue += (double) item.value
        * capacity / item.weight;

use:

break;

because the capacity is now full.


Recognition Cheat Sheet

If you see…Think…
Maximum value under capacityKnapsack
Fractions are allowedFractional Knapsack
Items can be splitFractional Knapsack
Maximum profit per unit weightValue/weight ratio
Take whole or partGreedy
0/1 — cannot split itemsDynamic Programming

My Private Notes

Notes are auto-saved locally to this device.