 GFG App
Open App Browser
Continue

# Maximize average of the ratios of N pairs by M increments

Given an array arr[] consisting of N pairs and a positive integer M, the task is to maximize the average of the ratio of the pairs by incrementing the first and second elements of any pair by 1 exactly M times.

Examples:

Input: arr[] = {{1, 2}, {3, 5}, {2, 2}}, M = 2
Output: 0.783333
Explanation:
Below are the operations performed:
Operation 1: Increment the first and second element of pair {1, 2} by 1. Now, the array modifies to {{2, 3}, {3, 5}, {2, 2}}.
Operation 2: Increment the first and second element of pair {2, 3} by 1. Now, the array modifies to {{3, 4}, {3, 5}, {2, 2}}.
After the above operations, the average of the ratio of the pairs is ((3/4) + (3/5) + (2/2))/3 = 0.7833 which is the maximum possible.

Input: arr[] = {{2, 5}, {3, 5}}, M = 3
Output: 0.619048

Approach: The given problem can be solved by storing the increase incurred in the ratio by applying operation on the pairs using Max-heap and then keep popping the values M times from the heap and add to the overall sum. Follow the steps below to solve the problem:

• Initialize a priority queue, say PQ of pairs to store the corresponding change in average and the index of the pair if one operation is applied on it.
• Initialize a variable, say sum as 0 to store the maximum average of the ratio of the pairs.
• Traverse the given array of pairs arr[] and find the increase in the ratio after adding 1 to both the values of the pair and push the value to priority queue PQ. Also, add the ratio of the ith pair to the variable sum.
• Iterate until the value of M is positive and perform the following steps:
• After completing the above steps, print the value of the sum divided by N as the result.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach`   `#include ` `using` `namespace` `std;`   `// Function to find the change in the` `// ratio in pair after applying operation` `double` `change(``int` `pass, ``int` `total)` `{` `    ``double` `currentPassRatio, newPassRatio;` `    ``double` `increase;`   `    ``// Stores the current ratio` `    ``currentPassRatio = ((``double``)pass)` `                       ``/ total;`   `    ``// Stores the new ratio` `    ``newPassRatio = ((``double``)(pass + 1))` `                   ``/ (total + 1);`   `    ``// Stores the increase in ratio` `    ``increase = newPassRatio` `               ``- currentPassRatio;`   `    ``// Returns the change` `    ``return` `increase;` `}`   `// Function to find the maximum` `// average of the ratio of the` `// pairs by applying M increments` `double` `maximumAverage(` `    ``vector > v, ``int` `M,` `    ``int` `N)` `{` `    ``// Stores the required result` `    ``double` `sum = 0;`   `    ``double` `increase, average;`   `    ``// Declare a priority queue` `    ``// for storing the increments` `    ``priority_queue > pq;` `    ``for` `(``int` `i = 0; i < N; i++) {`   `        ``// Store the increase in the ratio` `        ``// after applying one operation` `        ``increase = change(v[i], v[i]);`   `        ``// Push the increased value and` `        ``// index value in priority queue` `        ``pq.push({ increase, i });`   `        ``// Store the ratio` `        ``average = v[i] * 1.0 / v[i];`   `        ``// Update the value of sum` `        ``sum += average;` `    ``}`   `    ``// Iterate while M > 0` `    ``while` `(M > 0) {`   `        ``// Add the maximum change` `        ``// to the sum` `        ``sum += pq.top().first;`   `        ``int` `i = pq.top().second;`   `        ``// Remove the element from` `        ``// the priority queue` `        ``pq.pop();`   `        ``// Increase the pairs elements` `        ``// by 1 on which operation` `        ``// is applied` `        ``v[i] += 1;` `        ``v[i] += 1;`   `        ``// Push the updated change of` `        ``// the pair in priority queue` `        ``pq.push({ change(v[i], v[i]), i });`   `        ``// Decrease the operation count` `        ``M--;` `    ``}`   `    ``// Update the value of the sum by` `    ``// dividing it by N` `    ``double` `ans = sum / N;`   `    ``// Return the result` `    ``return` `ans;` `}`   `// Driver Code` `int` `main()` `{` `    ``vector > V` `        ``= { { 1, 2 }, { 3, 5 }, { 2, 2 } };` `    ``int` `M = 2;` `    ``int` `N = V.size();` `    ``cout << maximumAverage(V, M, N);`   `    ``return` `0;` `}`

## Java

 `import` `java.util.*;`   `// Comparer for the SortedList` `class` `DescendingComparer >` `  ``implements` `Comparator {` `  ``public` `int` `compare(T x, T y)` `  ``{` `    ``if` `(x == ``null``) {` `      ``return` `-``1``;` `    ``}` `    ``if` `(y == ``null``) {` `      ``return` `1``;` `    ``}`   `    ``return` `x.compareTo(y);` `  ``}` `}`   `class` `GFG {` `  ``// Function to find the change in the` `  ``// ratio in pair after applying operation` `  ``static` `double` `change(``int` `pass, ``int` `total)` `  ``{` `    ``double` `currentPassRatio, newPassRatio;` `    ``double` `increase;`   `    ``// Stores the current ratio` `    ``currentPassRatio = ((``double``)pass) / total;`   `    ``// Stores the new ratio` `    ``newPassRatio = ((``double``)(pass + ``1``)) / (total + ``1``);`   `    ``// Stores the increase in ratio` `    ``increase = newPassRatio - currentPassRatio;`   `    ``// Returns the change` `    ``return` `increase;` `  ``}`   `  ``// Function to find the maximum` `  ``// average of the ratio of the` `  ``// pairs by applying M increments` `  ``static` `double` `maximumAverage(List > v,` `                               ``int` `M, ``int` `N)` `  ``{` `    ``// Stores the required result` `    ``double` `sum = ``0``;`   `    ``double` `increase, average;`   `    ``// Declare a priority queue` `    ``// for storing the increments` `    ``PriorityQueue pq = ``new` `PriorityQueue<>(` `      ``new` `DescendingComparer());` `    ``for` `(``int` `i = ``0``; i < N; i++) {` `      ``// Store the increase in the ratio` `      ``// after applying one operation` `      ``increase` `        ``= change(v.get(i).get(``0``), v.get(i).get(``1``));`   `      ``// Push the increased value and` `      ``// index value in priority queue` `      ``pq.add(increase);`   `      ``// Store the ratio` `      ``average = v.get(i).get(``0``) * ``1.0` `        ``/ (``1.0` `* v.get(i).get(``1``));`   `      ``// Update the value of sum` `      ``sum += average;` `    ``}`   `    ``// Iterate while M > 0` `    ``while` `(M > ``0``) {` `      ``// Add the maximum change` `      ``// to the sum` `      ``// Remove the element from` `      ``// the priority queue` `      ``sum += pq.poll();`   `      ``// Decrease the operation count` `      ``M--;` `    ``}`   `    ``// Update the value of the sum by` `    ``// dividing it by N` `    ``double` `ans = sum / (``1.0` `* N);`   `    ``// Return the result` `    ``return` `ans;` `  ``}`   `  ``// Main function` `  ``public` `static` `void` `main(String[] args)` `  ``{` `    ``List > V = ``new` `ArrayList<>();` `    ``V.add(Arrays.asList(``1``, ``2``));` `    ``V.add(Arrays.asList(``3``, ``5``));` `    ``V.add(Arrays.asList(``2``, ``2``));` `    ``int` `M = ``2``;` `    ``int` `N = V.size();` `    ``System.out.println(maximumAverage(V, M, N));` `  ``}` `}`   `// This code is contributed by phasing17.`

## Python3

 `# python program for the above approach`   `# Function to find the change in the` `# ratio in pair after applying operation` `def` `change(pas, total):`   `    ``# Stores the current ratio` `    ``currentPassRatio ``=` `pas``/` `total`   `    ``# Stores the new ratio` `    ``newPassRatio ``=` `(pas ``+` `1``) ``/` `(total ``+` `1``)`   `    ``# Stores the increase in ratio` `    ``increase ``=` `newPassRatio ``-` `currentPassRatio`   `    ``# Returns the change` `    ``return` `increase`   `# Function to find the maximum` `# average of the ratio of the` `# pairs by applying M increments` `def` `maximumAverage(v, M, N):` `  `  `    ``# Stores the required result` `    ``sum` `=` `0`   `    ``increase, average ``=` `0``, ``0`   `    ``# Declare a priority queue` `    ``# for storing the increments` `    ``pq ``=` `[]` `    ``for` `i ``in` `range``(N):` `        ``# Store the increase in the ratio` `        ``# after applying one operation` `        ``increase ``=` `change(v[i][``0``], v[i][``1``])`   `        ``# Push the increased value and` `        ``# index value in priority queue` `        ``pq.append([increase, i ])`   `        ``# Store the ratio` `        ``average ``=` `v[i][``0``] ``*` `1.0` `/` `v[i][``1``]`   `        ``# Update the value of sum` `        ``sum` `+``=` `average` `    ``pq ``=` `sorted``(pq)`   `    ``# Iterate while M > 0` `    ``while` `(M > ``0``):`   `        ``# Add the maximum change` `        ``# to the sum` `        ``sum` `+``=` `pq[``-``1``][``0``]`   `        ``i ``=` `pq[``-``1``][``1``]`   `        ``# Remove the element from` `        ``# the priority queue` `        ``del` `pq[``-``1``]`   `        ``# Increase the pairs elements` `        ``# by 1 on which operation` `        ``# is applied` `        ``v[i][``0``] ``+``=` `1` `        ``v[i][``1``] ``+``=` `1`   `        ``# Push the updated change of` `        ``# the pair in priority queue` `        ``pq.append([change(v[i][``0``], v[i][``1``]), i])`   `        ``# Decrease the operation count` `        ``M ``-``=` `1` `        ``pq ``=` `sorted``(pq)`   `    ``# Update the value of the sum by` `    ``# dividing it by N` `    ``ans ``=` `sum` `/` `N`   `    ``# Return the result` `    ``return` `ans`   `# Driver Code` `if` `__name__ ``=``=` `'__main__'``:` `    ``V ``=`  `[[``1``, ``2``],  [``3``, ``5``],  [``2``, ``2``]]` `    ``M ``=` `2` `    ``N ``=` `len``(V)` `    ``print` `(``round``(maximumAverage(V, M, N),``6``))`   `    ``# This code is contributed by mohit kumar 29.`

## C#

 `// C# Program to find maximum average of the ratio of the pairs` `// by applying M increments` `using` `System;` `using` `System.Collections.Generic;` `using` `System.Linq;`   `// Comparer for the SortedList` `class` `DescendingComparer : IComparer {` `  ``public` `int` `Compare(T x, T y)` `  ``{` `    ``if` `(x == ``null``)` `      ``return` `-1;` `    ``if` `(y == ``null``)` `      ``return` `1;` `    ``return` `Comparer.Default.Compare(y, x);` `  ``}` `}`   `class` `Program {` `  ``// Function to find the change in the` `  ``// ratio in pair after applying operation` `  ``static` `double` `Change(``int` `pass, ``int` `total)` `  ``{` `    ``double` `currentPassRatio, newPassRatio;` `    ``double` `increase;`   `    ``// Stores the current ratio` `    ``currentPassRatio = ((``double``)pass) / total;`   `    ``// Stores the new ratio` `    ``newPassRatio = ((``double``)(pass + 1)) / (total + 1);`   `    ``// Stores the increase in ratio` `    ``increase = newPassRatio - currentPassRatio;`   `    ``// Returns the change` `    ``return` `increase;` `  ``}`   `  ``// Function to find the maximum` `  ``// average of the ratio of the` `  ``// pairs by applying M increments` `  ``static` `double` `MaximumAverage(List > v, ``int` `M,` `                               ``int` `N)` `  ``{` `    ``// Stores the required result` `    ``double` `sum = 0;`   `    ``double` `increase, average;`   `    ``// Declare a priority queue` `    ``// for storing the increments` `    ``var` `pq = ``new` `SortedList<``double``, ``int``>(` `      ``new` `DescendingComparer<``double``>());` `    ``for` `(``int` `i = 0; i < N; i++) {` `      ``// Store the increase in the ratio` `      ``// after applying one operation` `      ``increase = Change(v[i], v[i]);`   `      ``// Push the increased value and` `      ``// index value in priority queue` `      ``pq.Add(increase, i);`   `      ``// Store the ratio` `      ``average = v[i] * 1.0 / v[i];`   `      ``// Update the value of sum` `      ``sum += average;` `    ``}`   `    ``// Iterate while M > 0` `    ``while` `(M > 0) {` `      ``// Add the maximum change` `      ``// to the sum` `      ``sum += pq.First().Key;`   `      ``int` `i = pq.First().Value;`   `      ``// Remove the element from` `      ``// the priority queue` `      ``pq.RemoveAt(0);`   `      ``// Increase the pairs elements` `      ``// by 1 on which operation` `      ``// is applied` `      ``v[i] += 1;` `      ``v[i] += 1;`   `      ``// Push the updated change of` `      ``// the pair in priority queue` `      ``pq.Add(Change(v[i], v[i]), i);`   `      ``// Decrease the operation count` `      ``M--;` `    ``}`   `    ``// Update the value of the sum by` `    ``// dividing it by N` `    ``double` `ans = sum / N;`   `    ``// Return the result` `    ``return` `ans;` `  ``}`   `  ``// Main function` `  ``static` `void` `Main(``string``[] args)` `  ``{` `    ``var` `V` `      ``= ``new` `List >{ ``new` `List<``int``>{ 1, 2 },` `                             ``new` `List<``int``>{ 3, 5 },` `                             ``new` `List<``int``>{ 2, 2 } };` `    ``int` `M = 2;` `    ``int` `N = V.Count;` `    ``Console.WriteLine(MaximumAverage(V, M, N));` `  ``}` `}`   `// This code is contributed by phasing17.`

## Javascript

 ``

Output:

`0.783333`

Time Complexity: O(M*log N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up