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

• Last Updated : 01 Feb, 2023

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][0], v[i][1]);` `        ``// Push the increased value and``        ``// index value in priority queue``        ``pq.push({ increase, i });` `        ``// Store the ratio``        ``average = v[i][0] * 1.0 / v[i][1];` `        ``// 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][0] += 1;``        ``v[i][1] += 1;` `        ``// Push the updated change of``        ``// the pair in priority queue``        ``pq.push({ change(v[i][0], v[i][1]), 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;``}`

## 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][0], v[i][1]);` `      ``// Push the increased value and``      ``// index value in priority queue``      ``pq.Add(increase, i);` `      ``// Store the ratio``      ``average = v[i][0] * 1.0 / v[i][1];` `      ``// 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][0] += 1;``      ``v[i][1] += 1;` `      ``// Push the updated change of``      ``// the pair in priority queue``      ``pq.Add(Change(v[i][0], v[i][1]), 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