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.
Submitting an official solution before solving the problem yourself is a bannable offence.
Approach
Sort the items by decreasing value density .
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_valuefor the sum of fully taken items;- one fraction
frac_num / frac_denfor the final partial item.
Then the total answer is
.
We can keep this value as an exact fraction until the end, then print it as a floating-point
number.
Time complexity is 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