Open In App

Maximum sum of pair values such that value of pairs of same group should be a multiple of i in range [1, N]

Last Updated : 15 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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:

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.


 
 

Output: 

43 43 43 32 38 43

 

 

Time Complexity: O(N2)
Auxiliary Space: O(N)

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads