Algorithm

double fractionalKnapsack(int W, int[] value, int[] weight) {
  Integer[] idx = new Integer[value.length];
  for (int i = 0; i < idx.length; i++) idx[i] = i;
  Arrays.sort(idx, (a, b) -> Double.compare(
    (double) value[b] / weight[b], (double) value[a] / weight[a]));
  double total = 0;
  int remaining = W;
  for (int i : idx) {
    if (weight[i] <= remaining) { total += value[i]; remaining -= weight[i]; }
    else { total += (double) value[i] * remaining / weight[i]; break; }
  }
  return total;
}
Advertisement

Why greedy works

Exchange argument: swapping any part of high-ratio item for low-ratio item can only decrease value.

Advertisement

vs 0/1 knapsack

0/1 is NP-hard (needs DP). Fractional is P (greedy). Continuity is the reason.

Applications

Portfolio optimization (divisible investments). Resource allocation with fractional resources.