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++ 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 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 |
# 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# 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 |
<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>
|
27
Time Complexity: O(N*logN), as we are using a sort function.
Auxiliary Space: O(N), as we are using extra space.