Related Articles

# Fractional Knapsack Queries

• Difficulty Level : Easy
• Last Updated : 30 Aug, 2019

Given an integer array, consisting of positive weights “W” and there values “V” respectively as a pair and some queries consisting of an integer ‘C’ specifying the capacity of the knapsack, find the maximum value of products that can be put in the knapsack if the breaking of items is allowed.

Examples:

Input: arr[] = { {1, 2}, {1, 3}, {3, 7} }, q = {1, 2, 3, 4, 5}
Output: {3, 5.33333, 7.66667, 10, 12}
For ‘C’ = 1, we will fill the knap-sack with element of value 3.
For ‘C’ = 2, first, we fill with element of value 3, then remaining 1 capacity
with element with value 7.
For ‘C’ = 3, first we fill with element of value 3, then remaining 2 capacities
with element with value 7.
For ‘C’ = 4, first we fill with element of value 3, then remaining 3 capacities
with element with value 7.
For ‘C’ = 5, first we fill with element of value 3, next 3 capacities
with element with value 7 and remaining 1 with element of value 1.

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Naive Approach: A simple approach will be to sort the array in decreasing order of V/W values i.e. there value/weight ratio. Then, for each query, we will iterate the array sum up the required integer values while the knap-sack isn’t completely full.
Time Complexity : O(q*n*log(n))

Efficient approach: Queries can be optimized by performing prefix_sum of a sorted array on both weight and value.
Below is the algorithm:

1. Sort the array by there Value/Weight ratio in descending order.
2. Find prefix-sum of Weight and Value respectively of the array.

• Perform a binary search to find the first element with prefix_sum on weight(W) larger than ‘C’. Strictly speaking, find upper bound on the value of ‘C’ in a prefix_sum array of ‘W’. Let’s say this element is at an index ‘X’.
• Include sum of values from index {0, X-1} and the fractional value from index ‘X’ that can be accommodated in remaining capacity.

Below is the implementation of the above approach:

 `// C++ program to implement above approach``#include ``using` `namespace` `std;`` ` `// Function on the basis of which we will``// perform the sorting``bool` `comp(pair<``int``, ``int``> a, pair<``int``, ``int``> b)``{``    ``return` `(``double``)a.second / a.first >``                   ``(``double``)b.second / b.first;``}`` ` `// Function to sort the array on its value/weight``// and perform-sum on both weight and value``void` `preProcess(pair<``int``, ``int``> arr[], ``int` `n)``{``    ``sort(arr, arr + n, comp);``    ``for` `(``int` `i = 1; i < n; i++) {``        ``arr[i].first += arr[i - 1].first;``        ``arr[i].second += arr[i - 1].second;``    ``}``}`` ` `// Function to answer queries``double` `maxValue(``int` `w, pair<``int``, ``int``> arr[], ``int` `n)``{``    ``// If w is large enough``    ``// to cover all weights``    ``if` `(arr[n - 1].first <= w)``        ``return` `arr[n - 1].second;`` ` `    ``// Value to search on arr``    ``pair<``int``, ``int``> search_bound = { w, INT_MAX };`` ` `    ``// Index of the item which we will put``    ``// partially in our knap-sack``    ``int` `x = upper_bound(arr, arr + n, search_bound) - arr;`` ` `    ``// Required value``    ``if` `(x == 0)``        ``return` `(``double``)w * arr.second / arr.first;``    ``else``        ``return` `arr[x - 1].second +``              ``(``double``)(w - arr[x - 1].first) * ``              ``(arr[x].second - arr[x - 1].second) /``              ``(arr[x].first - arr[x - 1].first);``}`` ` `void` `PrintQueries(``int` `query[], pair<``int``, ``int``> arr[],``                                        ``int` `n, ``int` `m)``{``    ``for` `(``int` `i = 0; i < m; i += 1) {``        ``cout << maxValue(query[i], arr, n) << endl;``    ``}``}`` ` `// Driver code``int` `main()``{``    ``// Input array representing the data of w[] and v[]``    ``pair<``int``, ``int``> arr[] = { { 1, 2 }, { 1, 3 }, { 3, 7 } };``    ``int` `query = { 1, 2, 3, 4, 5 };`` ` `    ``// Size of the array``    ``int` `n = ``sizeof``(arr) / ``sizeof``(pair<``int``, ``int``>);``    ``int` `m = ``sizeof``(query) / ``sizeof``(query);`` ` `    ``// Pre-processing``    ``preProcess(arr, n);`` ` `    ``PrintQueries(query, arr, n, m);`` ` `    ``return` `0;``}`
Output:
```3
5.33333
7.66667
10
12
```

Time Complexity : O((n+q)*log(n))

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up