Opening the reading…
Opening the reading…
GREEDY › PART I
Open — the attempt gate is not wired up yet
This editorial is meant to unlock after you have run the problem at least once, with the worked solution behind one further deliberate click. That needs per-learner unlock state nothing stores today, so for now the whole article is open.
Try it yourself first →An item is not valuable merely because its total value is large. Since items can be split, the useful quantity is value per unit of weight: val[i] / wt[i]. An item worth 6 per unit weight is always a better use of the next unit of capacity than an item worth 4, regardless of their total sizes.
Take items in descending order of this density. If the next item fits, take it completely. If it does not fit, take exactly the fraction that fills the remaining capacity and stop. Any capacity assigned to a lower-density item while a higher-density item remains available could be exchanged for the higher-density material and would not reduce the total value.
| MEASURE | BOUND | WHY |
|---|---|---|
| Time | O(n log n) | Building the order takes O(n), sorting n indices takes O(n log n), and the final scan examines each sorted index at most once. The sorting term dominates, regardless of which item becomes fractional. |
| Space | O(n) extra | The index order stores one integer per item, while the answer and remaining capacity use constant extra space. The returned numeric value is required output and is excluded from the space bound; the extra space remains O(n) for every input shape. |
#include <algorithm>
#include <vector>
using namespace std;
class Solution {
public:
double fractionalKnapsack(vector<int>& val, vector<int>& wt, int capacity) {
int n = static_cast<int>(val.size());
vector<int> order(n);
for (int i = 0; i < n; ++i) {
order[i] = i;
}
sort(order.begin(), order.end(), [&](int a, int b) {
long long left = 1LL * val[a] * wt[b];
long long right = 1LL * val[b] * wt[a];
if (left != right) {
return left > right;
}
return a < b;
});
long double answer = 0.0L;
long long remaining = capacity;
for (int id : order) {
if (remaining == 0) {
break;
}
long long taken = min(remaining, static_cast<long long>(wt[id]));
answer += static_cast<long double>(taken) * val[id] / wt[id];
remaining -= taken;
}
return static_cast<double>(answer);
}
};The comparator avoids calculating val[i] / wt[i] while sorting. Comparing val[a] / wt[a] and val[b] / wt[b] directly would require division and can introduce unnecessary precision concerns; cross multiplication compares the same fractions exactly. The 1LL cast makes the products long long, and the accumulation uses long double so fractional contributions retain more precision before the required double return.