Maximum sum of pair values such that value of pairs of same group should be a multiple of i in range [1, N]
Given an array of pairs arr[] of size N, where the first element of the pair is the value of the pair and the second element is the group at which this pair belongs, the task is to find the maximum sum of pair values, such that the number of pairs of the same group should be a multiple of i for all i in the range [1, N].
Examples:
Input: arr[] = {{5, 3}, {9, 3}, {6, 3}, {7, 3}, {9, 3}, {7, 3}}, N = 6
Output : {43, 43, 43, 32, 38, 43}
Explanation:
There are 6 pairs of groups 3.
For i = 1, select all the pairs of group 3, since 6 % 1 = 0, then the sum will be 5 + 9 + 6 + 7 + 9 + 7 = 43.
For i = 2, select all the pairs of group 3 since 6 % 2 = 0, then the sum will be 5 + 9 + 6 + 7 + 9 + 7 = 43.
For i = 3, select all the pairs of group 3 since 6 % 3 = 0, then the sum will be 5 + 9 + 6 + 7 + 9 + 7 = 43.
For i = 4, select 4 pairs of group 3 whose sum of value is largest, then the sum will be 9 + 9 + 7 + 7 = 32.
For i = 5, select 5 pairs of group 3 whose sum of value is largest, then the sum will be 9 + 9 + 7 + 7 + 6 = 38.
For i = 6, select all the pairs of group 3 since 6 % 6 = 0, then the sum will be 5 + 9 + 6 + 7 + 9 + 7 = 43.Input: arr[] = {{6, 1}, {8, 2}, {3, 1}, {1, 2}, {5, 1}, {1, 2}, {5, 1}}, N = 7
Output : {29, 28, 26, 19, 0, 0, 0}
Approach: The simplest idea to solve the problem is to segregate the elements of the array on the basis of the group and then use the prefix sum array to find the sum of elements from each group in O(1). Follow the steps below to solve the problem:
- Initialize a hash map m with the first element as integer and the second element as vector.
- Iterate in the range [1, N] using the variable i and insert all the pairs of the vector in their respective groups.
- Sort all the vectors in the hash map in ascending order and store them in a vector say v.
- Initialize vectors say, ans of size N and it to store answers for all i in the range [1, N] and the prefix sum array for each group respectively.
- Iterate in the range [0, v.size()-1] using the variable i and perform the following steps:
- Initialize a vector c and Iterate in the range [0, v[i].size()-1] using the variable j and perform the following steps:
- If j is equal to 0, then append v[i][j] to the vector c, otherwise append c.back() + v[i][j].
- Insert the vector c in the vector it.
- Initialize a vector c and Iterate in the range [0, v[i].size()-1] using the variable j and perform the following steps:
- Now, iterate through the vector it using the variable i and perform the following steps:
- Iterate in the range [1, it[i].size()] using the variable j and perform the following steps:
- Store the number of elements that cannot be taken if j elements are chosen from the vector it[i] in the variable left.
- Add it[i].back() – it[i][left-1](Subtracting the left smallest number) in the ans[j-1].
- Iterate in the range [1, it[i].size()] using the variable j and perform the following steps:
- After performing the above steps, print the vector ans.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to find the maximum sum of // pair values, such that the number of // pairs of the same group should be a // multiple of i for all i in the // range [1, N] void findMaximumSumValue(vector<pair< int , int > > arr, int n) { // Map for storing elements of same group // together map< int , vector< int > > mp; // Segregate students on the basis of group for ( int i = 0; i < n; i++) { mp[arr[i].second - 1].push_back(arr[i].first); } vector<vector< int > > v; // Pushing all the vectors in the map to v for ( auto i : mp) { v.push_back(i.second); // Sort all the groups in ascending order sort(v.back().begin(), v.back().end()); } // Vector to store answer vector< int > ans(n, 0); // Vector to store prefix sum array // for each group vector<vector< int > > it; // Traverse through the groups for ( auto i : v) { vector< int > c; // Save prefix sum array in vector C for ( int j = 0; j < ( int )i.size(); j++) { if (j == 0) { c.push_back(i[j]); } else { c.push_back(c.back() + i[j]); } } // Insert the prefix sum c in it it.push_back(c); } // Traverse through the prefix function of each group for ( auto i : it) { // Traverse for all number of elements in i for ( int j = 1; j <= ( int )i.size(); j++) { // Check the number students to be left. int left = ( int )i.size() % j; int del = 0; // If left is greater than 0 subtract the // value of left smallest elements if (left > 0) del = i[left - 1]; ans[j - 1] += (i.back() - del); } } // Print the answer list for every // possible size for ( int i = 0; i < n; i++) { cout << ans[i] << " " ; } cout << endl; } // Driver Code int main() { // Given Input vector<pair< int , int > > arr = { { 5, 3 }, { 9, 3 }, { 6, 3 }, { 7, 3 }, { 9, 3 }, { 7, 3 } }; int N = arr.size(); // Function Call findMaximumSumValue(arr, N); return 0; } |
Java
import java.util.*; // Pair class definition class Pair<F, S> { public F first; public S second; // Constructor public Pair(F first, S second) { this .first = first; this .second = second; } // Getter methods public S getValue() { return second; } public F getKey() { return first; } } class GFG { // Function to find the maximum sum of // pair values, such that the number of // pairs of the same group should be a // multiple of i for all i in the // range [1, N] static void findMaximumSumValue(List<Pair<Integer, Integer> > arr, int n) { // Map for storing elements of same group together Map<Integer, List<Integer> > mp = new HashMap<>(); // Segregate students on the basis of group for ( int i = 0 ; i < n; i++) { if (!mp.containsKey(arr.get(i).getValue() - 1 )) { mp.put(arr.get(i).getValue() - 1 , new ArrayList<>()); } mp.get(arr.get(i).getValue() - 1 ) .add(arr.get(i).getKey()); } List<List<Integer> > v = new ArrayList<>(); // Pushing all the lists in the map to v for (Map.Entry<Integer, List<Integer> > i : mp.entrySet()) { v.add(i.getValue()); // Sort all the groups in ascending order Collections.sort(v.get(v.size() - 1 )); } // List to store answer List<Integer> ans = new ArrayList<>(Collections.nCopies(n, 0 )); // List to store prefix sum list // for each group List<List<Integer> > it = new ArrayList<>(); // Traverse through the groups for (List<Integer> i : v) { List<Integer> c = new ArrayList<>(); // Save prefix sum list in list C for ( int j = 0 ; j < i.size(); j++) { if (j == 0 ) { c.add(i.get(j)); } else { c.add(c.get(c.size() - 1 ) + i.get(j)); } } // Insert the prefix sum c in it it.add(c); } // Traverse through the prefix function of each // group for (List<Integer> i : it) { // Traverse for all number of elements in i for ( int j = 1 ; j <= i.size(); j++) { // Check the number students to be left. int left = i.size() % j; int del = 0 ; // If left is greater than 0 subtract the // value of left smallest elements if (left > 0 ) { del = i.get(left - 1 ); } ans.set(j - 1 , ans.get(j - 1 ) + (i.get(i.size() - 1 ) - del)); } } // Print the answer list for every // possible size System.out.println(ans); } // Driver Code public static void main(String[] args) { // Given Input List<Pair<Integer, Integer> > arr = new ArrayList<>(); arr.add( new Pair<>( 5 , 3 )); arr.add( new Pair<>( 9 , 3 )); arr.add( new Pair<>( 6 , 3 )); arr.add( new Pair<>( 7 , 3 )); arr.add( new Pair<>( 9 , 3 )); arr.add( new Pair<>( 7 , 3 )); int N = arr.size(); findMaximumSumValue(arr, N); } } // This code is contributed by phasing17 |
Python3
# Python 3 program for the above approach # Function to find the maximum sum of # pair values, such that the number of # pairs of the same group should be a # multiple of i for all i in the # range [1, N] def findMaximumSumValue(arr, n): # Map for storing elements of same group # together mp = {} # Segregate students on the basis of group for i in range (n): if (arr[i][ 1 ] - 1 ) not in mp: mp[arr[i][ 1 ] - 1 ] = [] mp[arr[i][ 1 ] - 1 ].append(arr[i][ 0 ]) v = [] # Pushing all the vectors in the map to v for i in mp: v.append(mp[i]) # Sort all the groups in ascending order v[ 0 ].sort() # Vector to store answer ans = [ 0 ] * (n) # Vector to store prefix sum array # for each group it = [] # Traverse through the groups for i in v: c = [] # Save prefix sum array in vector C for j in range ( len (i)): if (j = = 0 ): c.append(i[j]) else : c.append(c[ - 1 ] + i[j]) # Insert the prefix sum c in it it.append(c) # Traverse through the prefix function of each group for i in it: # Traverse for all number of elements in i for j in range ( 1 , len (i) + 1 ): # Check the number students to be left. left = len (i) % j dele = 0 # If left is greater than 0 subtract the # value of left smallest elements if (left > 0 ): dele = i[left - 1 ] ans[j - 1 ] + = (i[ - 1 ] - dele) # Print the answer list for every # possible size for i in range (n): print (ans[i], end = " " ) print () # Driver Code if __name__ = = "__main__" : # Given Input arr = [[ 5 , 3 ], [ 9 , 3 ], [ 6 , 3 ], [ 7 , 3 ], [ 9 , 3 ], [ 7 , 3 ]] N = len (arr) # Function Call findMaximumSumValue(arr, N) # This code is contributed by ukasp. |
C#
// C# code for the above approach using System; using System.Collections.Generic; class GFG { // Function to find the maximum sum of // pair values, such that the number of // pairs of the same group should be a // multiple of i for all i in the // range [1, N] static void FindMaximumSumValue(List<Tuple< int , int >> arr, int n) { // Dictionary for storing elements of same group together Dictionary< int , List< int >> mp = new Dictionary< int , List< int >>(); // Segregate students on the basis of group for ( int i = 0; i < n; i++) { if (!mp.ContainsKey(arr[i].Item2 - 1)) { mp.Add(arr[i].Item2 - 1, new List< int >()); } mp[arr[i].Item2 - 1].Add(arr[i].Item1); } List<List< int >> v = new List<List< int >>(); // Pushing all the lists in the dictionary to v foreach (KeyValuePair< int , List< int >> i in mp) { v.Add(i.Value); // Sort all the groups in ascending order v[v.Count - 1].Sort(); } // List to store answer List< int > ans = new List< int >( new int [n]); // List to store prefix sum list // for each group List<List< int >> it = new List<List< int >>(); // Traverse through the groups foreach (List< int > i in v) { List< int > c = new List< int >(); // Save prefix sum list in list C for ( int j = 0; j < i.Count; j++) { if (j == 0) { c.Add(i[j]); } else { c.Add(c[c.Count - 1] + i[j]); } } // Insert the prefix sum c in it it.Add(c); } // Traverse through the prefix function of each group foreach (List< int > i in it) { // Traverse for all number of elements in i for ( int j = 1; j <= i.Count; j++) { // Check the number students to be left. int left = i.Count % j; int del = 0; // If left is greater than 0 subtract the // value of left smallest elements if (left > 0) { del = i[left - 1]; } ans[j - 1] += (i[i.Count - 1] - del); } } // Print the answer list for every // possible size Console.WriteLine( string .Join( " " , ans)); } // Driver Code static void Main( string [] args) { // Given Input List<Tuple< int , int >> arr = new List<Tuple< int , int >>(); arr.Add(Tuple.Create(5, 3)); arr.Add(Tuple.Create(9, 3)); arr.Add(Tuple.Create(6, 3)); arr.Add(Tuple.Create(7, 3)); arr.Add(Tuple.Create(9, 3)); arr.Add(Tuple.Create(7, 3)); int N = arr.Count; // Function call FindMaximumSumValue(arr, N); } } // This code is contributed by phasing17 |
Javascript
// JavaScript program for the above approach // Function to find the maximum sum of // pair values, such that the number of // pairs of the same group should be a // multiple of i for all i in the // range [1, N] function findMaximumSumValue(arr, n) { // Map for storing elements of same group // together let mp = {}; // Segregate students on the basis of group for (let i = 0; i < n; i++) { if (!mp[arr[i][1] - 1]) { mp[arr[i][1] - 1] = []; } mp[arr[i][1] - 1].push(arr[i][0]); } let v = []; // Pushing all the vectors in the map to v for (let i in mp) { v.push(mp[i]); // Sort all the groups in ascending order v[0].sort((a, b) => a - b); } // Vector to store answer let ans = Array(n).fill(0); // Vector to store prefix sum array // for each group let it = []; // Traverse through the groups for (let i of v) { let c = []; // Save prefix sum array in vector C for (let j = 0; j < i.length; j++) { if (j === 0) { c.push(i[j]); } else { c.push(c[c.length - 1] + i[j]); } } // Insert the prefix sum c in it it.push(c); } // Traverse through the prefix function of each group for (let i of it) { // Traverse for all number of elements in i for (let j = 1; j <= i.length; j++) { // Check the number students to be left. let left = i.length % j; let dele = 0; // If left is greater than 0 subtract the // value of left smallest elements if (left > 0) { dele = i[left - 1]; } ans[j - 1] += (i[i.length - 1] - dele); } } // Print the answer list for every // possible size console.log(ans.join( " " )); } // Driver Code ( function () { // Given Input let arr = [[5, 3], [9, 3], [6, 3], [7, 3], [9, 3], [7, 3]]; let N = arr.length; // Function Call findMaximumSumValue(arr, N); })(); // This code is contributed by phasing17. |
43 43 43 32 38 43
Time Complexity: O(N2)
Auxiliary Space: O(N)
Please Login to comment...