# Theft at World Bank

• Difficulty Level : Expert
• Last Updated : 11 Aug, 2021

Given a sac of capacity W, and two arrays A[] and B[] of length N, where A[i] represents the weight of an ith block of gold and B[i] represents the profit gained by taking the ith block of gold, the task is to find the maximum profit gained by taking some part or whole of a gold block with not perfect square weight, not exceeding the sac capacity.

Examples:

Input: A[]= {4, 5, 7}, B[] = {8, 5, 4), W = 10
Output: 7.857
Explanation:
One way to obtain the maximum profit is:

1. Take the whole second block, getting a profit of 5 and reducing the capacity to 5.
2. Take a fraction of 5/7 of the third block, getting a profit of (5/7)*4 = 2.857 and reducing the capacity to 0.

Thus, the maximum obtained profit is equal to (5+2.857 = 7.857), which is the maximum possible.

Input: A[]= {2, 5, 3}, B[] = {7, 6, 9), W = 8
Output: 19.600

Approach: The given problem can be solved using a greedy algorithm known as fractional Knapsack. Follow the steps below to solve the problem:

• Initialize a vector of pairs say V to store the pairs formed by taking array elements from the array B[] as the first element and the array elements from array B[] as the second element present at the same index.
• Iterate over the range [0, N] and if A[i] is not a, perfect square then push the pair {B[i], A[i]} into the vector V.
• Sort the vector V in descending order by a custom comparator by the ratios of the pairs.
• Initialize a variable say profit as 0 to store the maximum profit.
• Traverse the vector V and perform the following steps in each iteration:
• If the second element of the current pair is less than or equal to W, then increment profit by the first element of the pair, i.e taking the whole block of gold and then decrease W by the second element of the current pair.
• Otherwise, take an amount equal to the ratio of W and the second element of the current pair and store it in a variable P. Then increment profit by P*first element of the current pair and then break.
• Finally, after completing the above steps, print the value obtained in profit as the answer.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ` `using` `namespace` `std;`   `// Custom comparator` `bool` `comp(pair<``long` `long``, ``long` `long``> p1,` `          ``pair<``long` `long``, ``long` `long``> p2)` `{` `    ``long` `double` `a = p1.first, b = p1.second;` `    ``long` `double` `c = p2.first, d = p2.second;` `    ``long` `double` `val1 = 0, val2 = 0;` `    ``val1 = a / b;` `    ``val2 = c / d;`   `    ``return` `val1 > val2;` `}`   `// Function to find the maximum profit` `long` `double` `maximumProfit(``int` `A[], ``int` `B[], ``int` `N,` `                          ``long` `long` `W)` `{` `    ``// Stores the pairs of elements` `    ``// of B and A at the same index` `    ``vector > V;`   `    ``// Iterate over the range` `    ``//[0, N]` `    ``for` `(``int` `i = 0; i < N; i++) {`   `        ``long` `long` `temp = ``sqrt``(A[i]);`   `        ``// If current integer is` `        ``// perfect square` `        ``if` `(temp * temp == A[i])` `            ``continue``;`   `        ``// Push the pair of B[i]` `        ``// and A[i] in vector V` `        ``V.push_back({ B[i], A[i] });` `    ``}`   `    ``// Sorts the vector using` `    ``// the custom comparator` `    ``sort(V.begin(), V.end(), comp);`   `    ``// Stores the maximum profit` `    ``long` `double` `profit = 0.00;`   `    ``// Traverse the vector V` `    ``for` `(``int` `i = 0; i < V.size(); i++) {` `        ``// If V[i].second is less` `        ``// than W` `        ``if` `(V[i].second <= W) {` `            ``// Increment profit by` `            ``// V[i].first` `            ``profit += V[i].first;`   `            ``// Decrement V[i].second` `            ``// from W` `            ``W -= V[i].second;` `        ``}` `        ``// Otherwise` `        ``else` `{` `            ``// Update profit` `            ``profit += V[i].first` `                      ``* ((``long` `double``)W / V[i].second);` `            ``break``;` `        ``}` `    ``}` `    ``// Return the value of profit` `    ``return` `profit;` `}` `// Driver Code` `int` `main()` `{`   `    ``int` `N = 3;` `    ``long` `long` `W = 10;` `    ``int` `A[] = { 4, 5, 7 };` `    ``int` `B[] = { 8, 5, 4 };`   `    ``cout << maximumProfit(A, B, N, W) << endl;`   `    ``return` `0;` `}`

## Python3

 `# Python3 program for the above approach` `import` `math` `from` `functools ``import` `cmp_to_key`   `# Custom comparator` `def` `comparator(p1, p2):` `    `  `    ``a ``=` `p1[``0``]` `    ``b ``=` `p1[``1``]` `    ``c ``=` `p2[``0``]` `    ``d ``=` `p2[``1``]` `    ``val1 ``=` `a ``/` `b` `    ``val2 ``=` `c ``/` `d` `    ``return` `val1 > val2`   `# Function to find the maximum profit` `def` `maximumProfit(A, B, N, W):` `  `  `    ``# Stores the pairs of elements` `    ``# of B and A at the same index` `    ``V ``=` `[]`   `    ``# Iterate over the range [0,N]` `    ``for` `i ``in` `range``(``0``, N):` `      `  `        ``temp ``=` `int``(math.sqrt(A[i]))` `        `  `        ``# If current integer is` `        ``# perfect square` `        ``if` `temp ``*` `temp ``=``=` `A[i]:` `            ``continue` `        `  `        ``# Push the pair of B[i]` `        ``# and A[i] in vector V` `        ``V.append([B[i], A[i]])` `        `  `    ``# Sort the vector using` `    ``# the custom comparator` `    ``V ``=` `sorted``(V, key ``=` `cmp_to_key(comparator))` `    `  `    ``# Stores the maximum profit` `    ``profit ``=` `0.00` `    `  `    ``# Traverse the vector V` `    ``k ``=` `len``(V)` `    ``for` `i ``in` `range``(k):` `      `  `        ``# If V[i] is less` `        ``# than W` `        ``if` `V[i][``1``] <``=` `W:` `            `  `            ``# Increment profit by` `            ``# V[i]` `            ``profit ``+``=` `V[i][``0``]` `            `  `            ``# Decrement V[i]` `            ``# from W` `            ``W ``-``=` `V[i][``1``]` `            `  `        ``# Otherwise` `        ``else``:` `            `  `            ``# Update profit` `            ``profit ``+``=` `(V[i][``0``] ``*` `W) ``/` `V[i][``1``]` `            ``break` `            `  `    ``# Return the value of profit` `    ``return` `profit`   `# Driver Code` `if` `__name__ ``=``=` `'__main__'``:` `  `  `    ``N ``=` `3` `    ``W ``=` `10` `    ``A ``=` `[ ``4``, ``5``, ``7` `]` `    ``B ``=` `[ ``8``, ``5``, ``4` `]` `    `  `    ``print``(``round``(maximumProfit(A, B, N, W), ``5``))` `    `  `# This code is contributed by MuskanKalra1`

## Javascript

 ``

Output

`7.85714`

Time Complexity: O(N * log(N))
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up
Recommended Articles
Page :