Editorial for Fractional Knapsack


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Approach

Sort the items by decreasing value density v_i / w_i.

Under this problem's constraints, using that ratio directly as the Python sort key is fine, so we can keep the implementation simple.

After sorting, the greedy rule is optimal:

  • take each item completely while it still fits;
  • when the next item no longer fits, take exactly the remaining fraction of that one item;
  • stop.

Only one item can be taken fractionally, so we can keep:

  • whole_value for the sum of fully taken items;
  • one fraction frac_num / frac_den for the final partial item.

Then the total answer is (whole\_value \cdot frac\_den + frac\_num) / frac\_den. We can keep this value as an exact fraction until the end, then print it as a floating-point number.

Time complexity is O(n \log n) due to sorting.

Solution (Python)

import sys


def main() -> None:
    input = sys.stdin.readline
    n, capacity = map(int, input().split())
    items = [tuple(map(int, input().split())) for _ in range(n)]
    items.sort(key=lambda item: item[0] / item[1], reverse=True)

    whole_value = 0
    frac_num = 0
    frac_den = 1
    remaining = capacity

    for value, weight in items:
        if remaining == 0:
            break
        if weight <= remaining:
            whole_value += value
            remaining -= weight
        else:
            frac_num = value * remaining
            frac_den = weight
            break

    total_num = whole_value * frac_den + frac_num
    total_den = frac_den
    print(total_num / total_den)


if __name__ == "__main__":
    main()

Comments

There are no comments at the moment.