Maximum possible Array sum after performing given operations

• Difficulty Level : Easy
• Last Updated : 01 Sep, 2020

Given array arr[] of positive integers, an integer Q, and arrays X[] and Y[] of size Q. For each element in arrays X[] and Y[], we can perform the below operations:

• For each query from array X[] and Y[], select at most X[i] elements from array arr[] and replace all the selected elements with integer Y[i].
• After performing Q operations, the task is to obtain maximum sum from the array arr[].

Examples:

Input: arr[] = {5, 2, 6, 3, 8, 5, 4, 7, 9, 10}, Q = 3, X[] = {2, 4, 1}, Y[] = {4, 3, 10}
Output: 68
Explanation:
For i = 1,
We can replace atmost 2 elements from array arr[] with integer 4. Here 2 element of array arr[] are smaller than 4 so we will replace elements 2 and 3 from array arr[] with 4 and arr[] becomes {5, 4, 6, 4, 8, 5, 4, 7, 9, 10}.
For i = 2,
We can replace at most 4 elements from array ar[] with integer 3, but no element of array arr[] is smaller than 3. So we will not replace anything.
For i = 3,
We can replace at most 1 element from array arr[] with integer 10, 9 elements of array arr[] are smaller than 10. To get the maximum sum, we will replace the smallest element from array arr[] with 10. Array arr[] after 3rd operation = {5, 10, 6, 4, 8, 5, 10, 7, 9, 10 }. The maximum possible sum is 68.

Input: ar[] = {200, 100, 200, 300}, Q = 2, X[] = {2, 3}, Y[] = {100, 90}
Output: 800
Explanation:
For i = 1,
We can replace atmost 2 elements from array arr[] with integer 100, no element of array arr[] is smaller than 100. So we will replace 0 elements.
For i = 2,
We can replace at most 3 elements from array arr[] with integer 90, no element of array arr[] is smaller than 90. So we will replace 0 elements. So the maximum sum we can obtain after q operation is 800.

Naive Approach: The naive idea is to pick X[i] number elements from the array arr[]. If the elements in the array are less than Y[i] then update X[i] of such elements.

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

Efficient Approach: The idea is to use a priority queue to get the element with higher value before the element with lower value, precisely priority queue of pairs to store value with its frequency. Below are the steps:

• Insert each element of the array arr[] with their occurrence in the priority queue.
• For each element(say X[i]) in the array X[] do the following:
1. Choose at most X[i] number of minimum element from the priority queue.
2. Replace it with Y[i] if choose element is less than Y[i].
3. Insert back the replaced element into the priority queue with their corresponding frequency.
• After the above operations the array arr[] will have elements such that sum of all element is maximum. Print the sum.

Below is the implementation of the above approach:

C++

 // C++ implementation to find the// maximum possible sum of array// after performing given operations#include using namespace std;  // Function to get maximum// sum after q operationsvoid max_sum(int ar[], int n,             int q, int x[], int y[]){    int ans = 0, i;      // priority queue to    // get maximum sum    priority_queue > pq;      // Push pair, value and 1    // in the priority queue    for (i = 0; i < n; i++)        pq.push({ ar[i], 1 });      // Push pair, value (to be replaced)    // and number of elements (to be replaced)    for (i = 0; i < q; i++)        pq.push({ y[i], x[i] });      // Add top n elements from    // the priority queue    // to get max sum    while (n > 0) {          // pr is the pair        // pr.first is the value and        // pr.second is the occurrence        auto pr = pq.top();          // pop from the priority queue        pq.pop();          // Add value to answer        ans += pr.first * min(n, pr.second);          // Update n        n -= pr.second;    }      cout << ans << "\n";}  // Driver codeint main(){    int ar[] = { 200, 100, 200, 300 };    int n = (sizeof ar) / (sizeof ar);    int q = 2;    int x[] = { 2, 3 };    int y[] = { 100, 90 };    max_sum(ar, n, q, x, y);      return 0;}

Java

 // Java implementation to find the // maximum possible sum of array // after performing given operations import java.util.*;import java.lang.*;  class GFG{  static class pair{    int first, second;    pair(int first, int second)    {        this.first = first;        this.second = second;    }}  // Function to get maximum // sum after q operations static void max_sum(int ar[], int n, int q,                    int x[], int y[]) {     int ans = 0, i;       // priority queue to     // get maximum sum     PriorityQueue pq = new PriorityQueue<>(        (a, b) -> Integer.compare(a.second, b.second));       // Push pair, value and 1     // in the priority queue     for(i = 0; i < n; i++)         pq.add(new pair(ar[i], 1 ));       // Push pair, value (to be replaced)     // and number of elements (to be replaced)     for(i = 0; i < q; i++)         pq.add(new pair(y[i], x[i]));       // Add top n elements from     // the priority queue     // to get max sum     while (n > 0)    {                   // pr is the pair         // pr.first is the value and         // pr.second is the occurrence         pair pr = pq.peek();           // pop from the priority queue         pq.poll();           // Add value to answer         ans += pr.first * Math.min(n, pr.second);           // Update n         n -= pr.second;     }     System.out.println(ans); }   // Driver Codepublic static void main (String[] args){    int ar[] = { 200, 100, 200, 300 };     int n = ar.length;     int q = 2;     int x[] = { 2, 3 };     int y[] = { 100, 90 };          max_sum(ar, n, q, x, y); }}  // This code is contributed by offbeat
Output:
800

Time Complexity: O(N*log2N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up