Skip to content
Related Articles

Related Articles

Theft at World Bank

View Discussion
Improve Article
Save Article
  • Difficulty Level : Expert
  • Last Updated : 11 Aug, 2021
View Discussion
Improve Article
Save Article

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 <bits/stdc++.h>
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<pair<long long, long long> > 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][1] is less
        # than W
        if V[i][1] <= W:
             
            # Increment profit by
            # V[i][0]
            profit += V[i][0]
             
            # Decrement V[i][0]
            # 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




<script>
 
// JavaScript program for the above approach
 
 
// Custom comparator
function comp(p1, p2) {
    let a = p1[0], b = p1[1];
    let c = p2[0], d = p2[1];
    let val1 = 0, val2 = 0;
    val1 = Math.floor(a / b);
    val2 = Math.floor(c / d);
 
    return val1 > val2;
}
 
// Function to find the maximum profit
function maximumProfit(A, B, N, W) {
    // Stores the pairs of elements
    // of B and A at the same index
    let V = [];
 
    // Iterate over the range
    //[0, N]
    for (let i = 0; i < N; i++) {
 
        let temp = 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.push([B[i], A[i]]);
    }
 
    // Sorts the vector using
    // the custom comparator
    V.sort(comp);
 
    // Stores the maximum profit
    let profit = 0.00;
 
    // Traverse the vector V
    for (let i = 0; i < V.length; i++) {
        // If V[i][1] is less
        // than W
        if (V[i][1] <= W) {
            // Increment profit by
            // V[i][0]
            profit += V[i][0];
 
            // Decrement V[i][1]
            // 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.toFixed(5);
}
// Driver Code
 
 
let N = 3;
let W = 10;
let A = [4, 5, 7];
let B = [8, 5, 4];
 
document.write(maximumProfit(A, B, N, W) + "<br>");
 
</script>


Output

7.85714

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

 


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!