Maximize sum of profits for N items such that profit for ith item is product of its weight and count of distinct chosen values
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++
#include <bits/stdc++.h>
using namespace std;
bool comp(pair< int , int > a, pair< int , int > b)
{
if (a.second > b.second)
return false ;
return true ;
}
int maxProfit(vector<pair< int , int > >& arr,
int N)
{
set< int > items;
for ( int i = 0; i < N; i++) {
items.insert(arr[i].first);
}
sort(arr.begin(), arr.end(), comp);
int uniqCnt = items.size();
items.clear();
int maxProfit = 0;
int totWeight = 0;
for ( int i = 0; i < N; i++) {
if (!items.count(arr[i].first)) {
items.insert(arr[i].first);
maxProfit += items.size() * arr[i].second;
}
else
totWeight += arr[i].second;
}
maxProfit += totWeight * uniqCnt;
return maxProfit;
}
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
import java.util.*;
class GFG{
static class pair
{
int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
boolean comp(pair a, pair b)
{
if (a.second > b.second)
return false ;
return true ;
}
static int maxProfit(pair[] arr,
int N)
{
HashSet<Integer> items = new HashSet<Integer>();
for ( int i = 0 ; i < N; i++) {
items.add(arr[i].first);
}
Arrays.sort(arr,(a,b)->a.second-b.second);
int uniqCnt = items.size();
items.clear();
int maxProfit = 0 ;
int totWeight = 0 ;
for ( int i = 0 ; i < N; i++) {
if (!items.contains(arr[i].first)) {
items.add(arr[i].first);
maxProfit += items.size() * arr[i].second;
}
else
totWeight += arr[i].second;
}
maxProfit += totWeight * uniqCnt;
return maxProfit;
}
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));
}
}
|
Python3
def maxProfit(arr, N):
items = set ()
for i in range (N):
items.add(arr[i][ "first" ])
arr = sorted (arr, key = lambda i: i[ 'second' ])
uniqCnt = len (items)
items.clear()
maxProfit = 0
totWeight = 0
for i in range ( 0 , N):
if ( not (arr[i][ 'first' ]) in items):
items.add(arr[i][ 'first' ])
maxProfit + = len (items) * arr[i][ 'second' ]
else :
totWeight + = arr[i][ 'second' ]
maxProfit + = totWeight * uniqCnt
return maxProfit
arr = [
{ "first" : 1 , "second" : 4 },
{ "first" : 2 , "second" : 3 },
{ "first" : 1 , "second" : 2 },
{ "first" : 3 , "second" : 2 }
]
N = len (arr)
print (maxProfit(arr, N))
|
C#
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;
}
public int CompareTo(pair p)
{
return this .second - p.second;
}
}
static int maxProfit(pair[] arr,
int N)
{
HashSet< int > items = new HashSet< int >();
for ( int i = 0; i < N; i++) {
items.Add(arr[i].first);
}
Array.Sort(arr);
int uniqCnt = items.Count;
items.Clear();
int maxProfit = 0;
int totWeight = 0;
for ( int i = 0; i < N; i++) {
if (!items.Contains(arr[i].first)) {
items.Add(arr[i].first);
maxProfit += items.Count * arr[i].second;
}
else
totWeight += arr[i].second;
}
maxProfit += totWeight * uniqCnt;
return maxProfit;
}
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));
}
}
|
Javascript
<script>
function maxProfit(arr,
N) {
let items = new Set();
for (let i = 0; i < N; i++) {
items.add(arr[i].first);
}
arr.sort( function (a, b) { return a.second - b.second })
let uniqCnt = items.size;
items.clear();
let maxProfit = 0;
let totWeight = 0;
for (let i = 0; i < N; i++) {
if (!items.has(arr[i].first)) {
items.add(arr[i].first);
maxProfit += items.size * arr[i].second;
}
else
totWeight += arr[i].second;
}
maxProfit += totWeight * uniqCnt;
return maxProfit;
}
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));
</script>
|
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
Share your thoughts in the comments
Please Login to comment...