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

• Difficulty Level : Hard
• Last Updated : 07 Oct, 2021

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:

Attention reader! Don’t stop learning now. Get hold of all the important mathematical concepts for competitive programming with the Essential Maths for CP Course at a student-friendly price. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

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 = (1, 2). The profit for the current chosen item is 2 * 1 = 2.
• Choose the 3rd item i.e., arr = (3, 2). The profit for the current chosen item is 2 * 2 = 4.
• Choose the 1st item i.e., arr = (2, 3). The profit for the current chosen item is 3 * 3 = 9.
• Choose the 0th item i.e., arr = (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<``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 >& 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 > 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<``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

 ``

Output:
`27`

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

My Personal Notes arrow_drop_up