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

Last Updated : 31 May, 2022

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 using namespace std;   // Comparator function to sort vector // with respect to the second value bool 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 int maxProfit(vector >& arr,               int N) {       // Stores the unique items     set 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 > 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 items = new HashSet();       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     {         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 items = new HashSet();       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



Output:

27

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

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

Previous
Next