Fractional Knapsack maximizes total value when you can take fractions of items.
Ratio sort → full takes → one fractional cut → stop. Watch the bag fill:
⚠️ Animation & Content Notice
The animation work is not fully finished — some animations may have slight errors.
If there is a major error in the content or if the animation or content is difficult to understand, please contact us at rayyancodingschool@gmail.com.
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.)
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
| Pattern | Typical Questions | Trigger |
|---|---|---|
| Fractional Knapsack | Maximum value under capacity | Sort by value/weight |
| 0/1 Knapsack | Take whole items only | Dynamic 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_valuestruct 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 capacity | Knapsack |
| Fractions are allowed | Fractional Knapsack |
| Items can be split | Fractional Knapsack |
| Maximum profit per unit weight | Value/weight ratio |
| Take whole or part | Greedy |
| 0/1 — cannot split items | Dynamic Programming |
Premium Content
Unlock Fractional Knapsack and all premium lessons with a subscription.
From ₹199.99/year — See plans