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

• Last Updated : 06 Jul, 2021

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:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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;``}`

## 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.`

## Javascript

 ``
Output:
`0.783333`

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

My Personal Notes arrow_drop_up