Find subset with maximum sum under given condition
Last Updated :
09 Feb, 2023
Given values[] and labels[] of n items and a positive integer limit, We need to choose a subset of these items in such a way that the number of the same type of label in the subset should be <= limit and sum of values are maximum among all possible subset choices.
Examples:
Input: values[] = [5, 3, 7, 1, 2],
labels[] = [5, 7, 7, 7, 6],
limit = 2
Output: 17
Explanation:
You can select first, second, third
and Fifth values.
So, there is 1 value of the label 5 -> {5},
2 value of the label 7 -> {3, 7} ,
1 value of the label 6 -> {2}.
Final subset = {5, 3, 7, 2}
Sum = 5 + 3 + 7 + 2 = 17.
Input: values[] = [9, 8, 7, 6, 5],
labels[] = [5, 7, 7, 7, 6],
limit = 2
Output: 29
Approach: The idea is to use a Multimap and Hashmap to solve this problem.
- We will store all the values and the respective labels as a pair in the Multimap.
- In Multimap the {values, labels} pairs are sorted in increasing order. So, we will traverse the Multimap in reverse to get the pairs in decreasing order.
- Now, we will add the values in our answer and store the occurrence of each label in Hashmap to check if the number of occurrences is <= limit.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int MaxSumSubset(vector< int >& values,
vector< int >& labels,
int n, int limit)
{
int res = 0;
multimap< int , int > s;
unordered_map< int , int > map;
if (n == 0)
{
return 0;
}
for ( int i = 0; i < n; i++)
{
s.insert({ values[i], labels[i] });
}
for ( auto it = s.rbegin();
it != s.rend() && n > 0; it++)
{
cout<<(it->first)<< " " <<it->second<<endl;
if (++map[it->second] <= limit)
{
res += it->first;
n--;
}
}
return res;
}
int main()
{
vector< int > values = { 5, 3, 7, 1, 2 };
vector< int > labels = { 5, 7, 7, 7, 6 };
int n = sizeof (values) / sizeof (values[0]);
int limit = 2;
cout << MaxSumSubset(values, labels,
n, limit);
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;
}
}
static int MaxSumSubset( int [] values,
int [] labels,
int n, int limit)
{
int res = 0 ;
HashSet<Pair> s = new HashSet<>();
HashMap<Integer, Integer> map = new HashMap<>();
if (n == 0 )
{
return 0 ;
}
for ( int i = 0 ; i < n; i++)
{
s.add( new Pair(values[i],labels[i]));
}
for (Pair i:s){
if (!map.containsKey(i.second)){
map.put(i.second, 0 );
}
if (map.get(i.second)<limit){
map.put(i.second,map.get(i.second)+ 1 );
res += i.first;
n--;
}
}
return res;
}
public static void main (String[] args)
{
int [] values = { 5 , 3 , 7 , 1 , 2 };
int [] labels = { 5 , 7 , 7 , 7 , 6 };
int n = values.length;
int limit = 2 ;
System.out.println(MaxSumSubset(values, labels,n, limit));
}
}
|
Python3
from collections import defaultdict
def MaxSumSubset(values, labels,
n, limit):
res = 0
s = {}
map = defaultdict( int )
if (n = = 0 ):
return 0
for i in range (n):
s[values[i]] = labels[i]
for it in sorted (s.keys(), reverse = True ):
if n > 0 :
if ( map [s[it]] < limit):
res + = it
map [s[it]] + = 1
n - = 1
return res
if __name__ = = "__main__" :
values = [ 5 , 3 , 7 , 1 , 2 ]
labels = [ 5 , 7 , 7 , 7 , 6 ]
n = len (values)
limit = 2
print (MaxSumSubset(values, labels,
n, limit))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
public class Pair {
public int first, second;
public Pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
static int MaxSumSubset( int [] values, int [] labels,
int n, int limit)
{
int res = 0;
HashSet<Pair> s = new HashSet<Pair>();
Dictionary< int , int > map
= new Dictionary< int , int >();
if (n == 0) {
return 0;
}
for ( int i = 0; i < n; i++) {
s.Add( new Pair(values[i], labels[i]));
}
foreach (Pair i in s)
{
if (!map.ContainsKey(i.second)) {
map.Add(i.second, 0);
}
if (map[i.second] < limit) {
map[i.second] = map[i.second] + 1;
res += i.first;
n--;
}
}
return res;
}
static public void Main()
{
int [] values = { 5, 3, 7, 1, 2 };
int [] labels = { 5, 7, 7, 7, 6 };
int n = values.Length;
int limit = 2;
Console.WriteLine(
MaxSumSubset(values, labels, n, limit));
}
}
|
Javascript
<script>
function MaxSumSubset(values,labels,n,limit)
{
let res = 0;
let s= new Map();
let map= new Map();
if (n == 0)
{
return 0;
}
for (let i = 0; i < n; i++)
{
s.set( values[i],
labels[i] );
}
for (let [key,value] of s.entries())
{
if (!map.has(value))
map.set(value,0);
if (map.get(value) < limit)
{
map.set(value,map.get(value)+1);
res += key;
n--;
}
}
return res;
}
let values=[5, 3, 7, 1, 2];
let labels=[5, 7, 7, 7, 6];
let n= values.length;
let limit = 2;
document.write(MaxSumSubset(values, labels,n, limit));
</script>
|
Time Complexity: O(NlogN), where N is the length of the array, and multimap take O(logN) complexity for insertion and other operations.
Auxiliary Space: O(N), for storing all the elements in the array.
Share your thoughts in the comments
Please Login to comment...