Open In App

Maximize sum of profits for N items such that profit for ith item is product of its weight and count of distinct chosen values

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] consisting of N pairs of items as {value, weight}, the task is to find the maximum sum of profit by choosing all the given N items such that profit for choosing the ith item is calculated as the product of its weight and number of distinct values already taken.

Examples:

Input: arr[] = {(1, 4), (2, 3), (1, 2), (3, 2)}
Output: 27
Explanation:
Below is the order of choosing items to maximize the profit:

  • Choose the 2nd item i.e., arr[2] = (1, 2). The profit for the current chosen item is 2 * 1 = 2.
  • Choose the 3rd item i.e., arr[3] = (3, 2). The profit for the current chosen item is 2 * 2 = 4.
  • Choose the 1st item i.e., arr[1] = (2, 3). The profit for the current chosen item is 3 * 3 = 9.
  • Choose the 0th item i.e., arr[0] = (1, 4). The profit for the current chosen item is 4 * 3 = 12.

Therefore, the total profit is 2 + 4 + 9 + 12 = 27, which is maximum among all possible combination of chosen N pairs.

Input: arr[] = {(2, 2), (1, 2), (3, 2)}
Output: 12

Approach: The given problem can be solved by using the Greedy Approach. The idea is to sort the given array arr[] with respect to the weight of the items and all the distinct items are chosen first and then remaining items. Follow the steps below to solve the given problem:

  • Initialize a set, say items, to store all the unique items.
  • Initialize a variable, say uniqCnt = 0, to store the count of unique items.
  • Initialize a variable, say maxProfit = 0, to store the total maximum profit.
  • Initialize a variable, say totWeight = 0, to store the total weight of the items which are not unique.
  • Traverse the array arr[] and store all the unique items into the set items.
  • Sort the array arr[] in ascending order of their weights.
  • Store the count of unique elements as uniqCnt = items.size() and remove all the elements from the items.
  • Traverse the given array arr[] and check for the following condition:
    • if(!items.count(arr[i].first)) if this found to be true, then insert the arr[i].first element into the set items and calculate the profit and update it to the maxProfit by maxProfit += items.size() * arr[i].second.
    • Otherwise, update the totWeight as totWeight += arr[i].second.
  • Calculate the profit for the items which are not unique and update the maxProfit as maxProfit += totWeight * uniqCnt.
  • After completing the above steps, print the value of maxProfit as the resultant maximum profit.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Comparator function to sort vector
// with respect to the second value
bool comp(pair<int, int> a, pair<int, int> b)
{
    if (a.second > b.second)
        return false;
 
    return true;
}
 
// Function to maximize the total profit
// by choosing  the array of items in a
// particular order
int maxProfit(vector<pair<int, int> >& arr,
              int N)
{
 
    // Stores the unique items
    set<int> items;
 
    for (int i = 0; i < N; i++) {
 
        // Store all the unique items
        items.insert(arr[i].first);
    }
 
    // Sort the arr with respect to
    // the weights
    sort(arr.begin(), arr.end(), comp);
 
    // Stores the number of unique
    // items count
    int uniqCnt = items.size();
 
    // Clear the set items
    items.clear();
 
    // Stores the maximum profit
    int maxProfit = 0;
 
    // Stores the total weight of items
    // which are not unique
    int totWeight = 0;
 
    for (int i = 0; i < N; i++) {
 
        // Check the current item is unique
        if (!items.count(arr[i].first)) {
 
            // Insert the current item
            // into the items set
            items.insert(arr[i].first);
 
            // Calculate the profit for
            // the current item and
            // update the maxProfit
            maxProfit += items.size() * arr[i].second;
        }
        else
            // Update the totWeight by
            // adding current item weight
            totWeight += arr[i].second;
    }
 
    // Update the maxProfit by calculating
    // the profit for items which are not
    // unique and adding it to maxProfit
    maxProfit += totWeight * uniqCnt;
 
    // Return maxProfit
    return maxProfit;
}
 
// Driver Code
int main()
{
    vector<pair<int, int> > arr{
        { 1, 4 }, { 2, 3 }, { 1, 2 }, { 3, 2 }
    };
    int N = arr.size();
    cout << maxProfit(arr, N);
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
 
class GFG{
    static class pair
    {
        int first, second;
        public pair(int first, int second) 
        {
            this.first = first;
            this.second = second;
        }   
    }
// Comparator function to sort vector
// with respect to the second value
boolean comp(pair a, pair b)
{
    if (a.second > b.second)
        return false;
 
    return true;
}
 
// Function to maximize the total profit
// by choosing  the array of items in a
// particular order
static int maxProfit(pair[] arr,
              int N)
{
 
    // Stores the unique items
    HashSet<Integer> items = new HashSet<Integer>();
 
    for (int i = 0; i < N; i++) {
 
        // Store all the unique items
        items.add(arr[i].first);
    }
 
    // Sort the arr with respect to
    // the weights
    Arrays.sort(arr,(a,b)->a.second-b.second);
 
    // Stores the number of unique
    // items count
    int uniqCnt = items.size();
 
    // Clear the set items
    items.clear();
 
    // Stores the maximum profit
    int maxProfit = 0;
 
    // Stores the total weight of items
    // which are not unique
    int totWeight = 0;
 
    for (int i = 0; i < N; i++) {
 
        // Check the current item is unique
        if (!items.contains(arr[i].first)) {
 
            // Insert the current item
            // into the items set
            items.add(arr[i].first);
 
            // Calculate the profit for
            // the current item and
            // update the maxProfit
            maxProfit += items.size() * arr[i].second;
        }
        else
            // Update the totWeight by
            // adding current item weight
            totWeight += arr[i].second;
    }
 
    // Update the maxProfit by calculating
    // the profit for items which are not
    // unique and adding it to maxProfit
    maxProfit += totWeight * uniqCnt;
 
    // Return maxProfit
    return maxProfit;
}
 
// Driver Code
public static void main(String[] args)
{
    pair[] arr = {
            new pair( 1, 4 ), new pair( 2, 3 ), new pair( 1, 2 ), new pair( 3, 2 )
    };
    int N = arr.length;
    System.out.print(maxProfit(arr, N));
 
}
}
 
// This code is contributed by 29AjayKumar


Python3




# Python Program to implement
# the above approach
 
# Function to maximize the total profit
# by choosing  the array of items in a
# particular order
def maxProfit(arr, N):
 
    # Stores the unique items
    items = set()
 
    for i in range(N):
 
        # Store all the unique items
        items.add(arr[i]["first"])
 
    # Sort the arr with respect to
    # the weights
 
    arr = sorted(arr, key=lambda i: i['second'])
 
    # Stores the number of unique
    # items count
    uniqCnt = len(items)
 
    # Clear the set items
    items.clear()
 
    # Stores the maximum profit
    maxProfit = 0
 
    # Stores the total weight of items
    # which are not unique
    totWeight = 0
 
    for i in range(0, N):
 
        # Check the current item is unique
        if (not (arr[i]['first']) in items):
 
            # Insert the current item
            # into the items set
            items.add(arr[i]['first'])
 
            # Calculate the profit for
            # the current item and
            # update the maxProfit
            maxProfit += len(items) * arr[i]['second']
 
        else:
            # Update the totWeight by
            # adding current item weight
            totWeight += arr[i]['second']
 
    # Update the maxProfit by calculating
    # the profit for items which are not
    # unique and adding it to maxProfit
    maxProfit += totWeight * uniqCnt
 
    # Return maxProfit
    return maxProfit
 
 
# Driver Code
arr = [
    {"first": 1, "second": 4},
    {"first": 2, "second": 3},
    {"first": 1, "second": 2},
    {"first": 3, "second": 2}
]
N = len(arr)
print(maxProfit(arr, N))
 
# This code is contributed by gfgking


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG{
    public class pair : IComparable<pair>
    {
        public int first,second;
        public pair(int first, int second)
        {
            this.first = first;
            this.second = second; 
        }
 
        // Comparator function to sort vector
        // with respect to the second value
        public int CompareTo(pair p)
        {
            return this.second - p.second;
        }
    }
 
// Function to maximize the total profit
// by choosing  the array of items in a
// particular order
static int maxProfit(pair[] arr,
              int N)
{
 
    // Stores the unique items
    HashSet<int> items = new HashSet<int>();
 
    for (int i = 0; i < N; i++) {
 
        // Store all the unique items
        items.Add(arr[i].first);
    }   
 
    // Sort the arr with respect to
    // the weights
    Array.Sort(arr);
 
    // Stores the number of unique
    // items count
    int uniqCnt = items.Count;
 
    // Clear the set items
    items.Clear();
 
    // Stores the maximum profit
    int maxProfit = 0;
 
    // Stores the total weight of items
    // which are not unique
    int totWeight = 0;
 
    for (int i = 0; i < N; i++) {
 
        // Check the current item is unique
        if (!items.Contains(arr[i].first)) {
 
            // Insert the current item
            // into the items set
            items.Add(arr[i].first);
 
            // Calculate the profit for
            // the current item and
            // update the maxProfit
            maxProfit += items.Count * arr[i].second;
        }
        else
            // Update the totWeight by
            // adding current item weight
            totWeight += arr[i].second;
    }
 
    // Update the maxProfit by calculating
    // the profit for items which are not
    // unique and adding it to maxProfit
    maxProfit += totWeight * uniqCnt;
 
    // Return maxProfit
    return maxProfit;
}
 
// Driver Code
public static void Main(String[] args)
{
    pair[] arr = {
            new pair( 1, 4 ), new pair( 2, 3 ), new pair( 1, 2 ), new pair( 3, 2 )
    };
    int N = arr.Length;
    Console.Write(maxProfit(arr, N));
 
}
}
 
// This code is contributed by shikhasingrajput


Javascript




<script>
        // JavaScript Program to implement
        // the above approach
 
        // Function to maximize the total profit
        // by choosing  the array of items in a
        // particular order
        function maxProfit(arr,
            N) {
 
            // Stores the unique items
            let items = new Set();
 
            for (let i = 0; i < N; i++) {
 
                // Store all the unique items
                items.add(arr[i].first);
            }
 
            // Sort the arr with respect to
            // the weights
            arr.sort(function (a, b) { return a.second - b.second })
            // Stores the number of unique
            // items count
            let uniqCnt = items.size;
 
            // Clear the set items
            items.clear();
 
            // Stores the maximum profit
            let maxProfit = 0;
 
            // Stores the total weight of items
            // which are not unique
            let totWeight = 0;
 
            for (let i = 0; i < N; i++) {
 
                // Check the current item is unique
                if (!items.has(arr[i].first)) {
 
                    // Insert the current item
                    // into the items set
                    items.add(arr[i].first);
 
                    // Calculate the profit for
                    // the current item and
                    // update the maxProfit
                    maxProfit += items.size * arr[i].second;
                }
                else
                    // Update the totWeight by
                    // adding current item weight
                    totWeight += arr[i].second;
            }
 
            // Update the maxProfit by calculating
            // the profit for items which are not
            // unique and adding it to maxProfit
            maxProfit += totWeight * uniqCnt;
 
            // Return maxProfit
            return maxProfit;
        }
 
        // Driver Code
        let arr = [
            { "first": 1, "second": 4 },
            { "first": 2, "second": 3 },
            { "first": 1, "second": 2 },
            { "first": 3, "second": 2 }
        ]
        let N = arr.length;
        document.write(maxProfit(arr, N));
 
     // This code is contributed by Potta Lokesh
 
    </script>


Output: 

27

 

Time Complexity: O(N*logN), as we are using a sort function.

Auxiliary Space: O(N), as we are using  extra space.

 



Last Updated : 31 May, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads