Open In App

Sum of Array maximums after K operations by reducing max element to its half

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of N integers and an integer K, the task is to find the sum of maximum of the array possible wherein each operation the current maximum of the array is replaced with its half.

Example:

Input: arr[] = {2, 4, 6, 8, 10}, K = 5
Output: 33
Explanation: In 1st operation, the maximum of the given array is 10. Hence, the value becomes 10 and the array after 1st operation becomes arr[] = {2, 4, 6, 8, 5}. 
The value after 2nd operation = 18 and arr[] = {2, 4, 6, 4, 5}. 
Similarly, proceeding forward, value after 5th operation will be 33.

Input: arr[] = {6, 5}, K = 3
Output: 14

 

Approach: The given problem can be solved with the help of a greedy approach. The idea is to use a max heap data structure. Therefore, traverse the given array and insert all the elements in the array arr[] into a max priority queue. At each operation, remove the maximum from the heap using pop operation, add it to the value and reinsert the value after dividing it by two into the heap. The value after repeating the above operation K times is the required answer.

Below is the implementation of the above approach:

C++




// C++ program of the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find maximum possible
// value after K given operations
int maxValue(vector<int> arr, int K)
{
    // Stores required value
    int val = 0;
 
    // Initializing priority queue
    // with all elements of array
    priority_queue<int> pq(arr.begin(),
                           arr.end());
 
    // Loop to iterate through
    // each operation
    while (K--) {
 
        // Current Maximum
        int max = pq.top();
        pq.pop();
 
        // Update value
        val += max;
 
        // Reinsert maximum
        pq.push(max / 2);
    }
 
    // Return Answer
    return val;
}
 
// Driver Call
int main()
{
    vector<int> arr = { 2, 4, 6, 8, 10 };
    int K = 5;
    cout << maxValue(arr, K);
}


Java




// Java code for the above approach
import java.util.Comparator;
import java.util.PriorityQueue;
class CustomComparator implements Comparator<Integer> {
 
  @Override
  public int compare(Integer number1, Integer number2)
  {
    int value =  number1.compareTo(number2);
 
    // elements are sorted in reverse order
    if (value > 0) {
      return -1;
    }
    else if (value < 0) {
      return 1;
    }
    else {
      return 0;
    }
  }
}
class GFG {
 
  // Function to find maximum possible
  // value after K given operations
  static int maxValue(int[] arr, int K)
  {
 
    // Stores required value
    int val = 0;
 
    // Initializing priority queue
    // with all elements of array
    PriorityQueue<Integer> pq
      = new PriorityQueue<Integer>(new CustomComparator());
 
    for (int i = 0; i < arr.length; i++) {
      pq.add(arr[i]);
    }
 
    // Loop to iterate through
    // each operation
    while (K != 0) {
 
      // Current Maximum
      int max = pq.poll();
 
      // Update value
      val += max;
 
      // Reinsert maximum
      pq.add((int)Math.floor(max / 2));
      K = K - 1;
    }
 
    // Return Answer
    return val;
  }
 
  // Driver Call
  public static void main(String[] args)
  {
    int[] arr = { 2, 4, 6, 8, 10 };
    int K = 5;
    System.out.println(maxValue(arr, K));
  }
}
 
// This code is conbtributed by Potta Lokesh


Python3




# python3 program of the above approach
from queue import PriorityQueue
 
# Function to find maximum possible
# value after K given operations
def maxValue(arr, K):
 
    # Stores required value
    val = 0
 
    # Initializing priority queue
    # with all elements of array
    pq = PriorityQueue()
 
    for dt in arr:
        pq.put(-1*dt)
 
    # Loop to iterate through
    # each operation
    while (True):
 
        # Current Maximum
        max = -1 * pq.get()
 
        # Update value
        val += max
 
        # Reinsert maximum
        pq.put(-1 * (max // 2))
 
        K -= 1
 
        if K == 0:
            break
 
    # Return Answer
    return val
 
# Driver Call
if __name__ == "__main__":
 
    arr = [2, 4, 6, 8, 10]
    K = 5
    print(maxValue(arr, K))
 
    # This code is contributed by rakeshsahni


C#




// C# code for the above approach
using System;
using System.Collections.Generic;
 
class CustomComparator : IComparer<int> {
  public int Compare(int number1, int number2)
  {
    int value = number1.CompareTo(number2);
 
    // elements are sorted in reverse order
    if (value > 0) {
      return -1;
    }
    else if (value < 0) {
      return 1;
    }
    else {
      return 0;
    }
  }
}
 
public class GFG {
 
  // Function to find maximum possible
  // value after K given operations
  static int maxValue(int[] arr, int K)
  {
 
    // Stores required value
    int val = 0;
 
    // Initializing priority queue
    // with all elements of array
    SortedSet<int> pq
      = new SortedSet<int>(new CustomComparator());
    for (int i = 0; i < arr.Length; i++) {
      pq.Add(arr[i]);
    }
 
    // Loop to iterate through each operation
    while (K != 0) {
      // Current Maximum
      int max = pq.Min;
 
      // Update value
      val += max;
 
      // Reinsert maximum
      pq.Add((int)Math.Floor((double)max / 2));
      pq.Remove(max);
      K = K - 1;
    }
 
    // Return Answer
    return val;
  }
 
  static public void Main()
  {
 
    // Code
    int[] arr = { 2, 4, 6, 8, 10 };
    int K = 5;
    Console.WriteLine(maxValue(arr, K));
  }
}
 
// This code is conbtributed by lokesh.


Javascript




class PriorityQueue {
  constructor(comparator) {
    this.heap = [];
    this.comparator = comparator;
  }
 
  add(element) {
    this.heap.push(element);
    this.bubbleUp(this.heap.length - 1);
  }
 
  peek() {
    return this.heap[0];
  }
 
  poll() {
    const poppedValue = this.heap[0];
    const bottom = this.heap.length - 1;
    if (bottom > 0) {
      this.swap(0, bottom);
    }
    this.heap.pop();
    this.bubbleDown(0);
    return poppedValue;
  }
 
  size() {
    return this.heap.length;
  }
 
  bubbleUp(index) {
    while (index > 0) {
      const parentIndex = Math.floor((index + 1) / 2) - 1;
      if (this.comparator(this.heap[index], this.heap[parentIndex]) < 0) {
        this.swap(index, parentIndex);
        index = parentIndex;
      } else {
        break;
      }
    }
  }
 
  bubbleDown(index) {
    let swapping = true;
    while (swapping) {
      const leftChildIndex = 2 * (index + 1) - 1;
      const rightChildIndex = 2 * (index + 1);
      let minIndex = index;
      if (
        leftChildIndex < this.heap.length &&
        this.comparator(this.heap[leftChildIndex], this.heap[minIndex]) < 0
      ) {
        minIndex = leftChildIndex;
      }
      if (
        rightChildIndex < this.heap.length &&
        this.comparator(this.heap[rightChildIndex], this.heap[minIndex]) < 0
      ) {
        minIndex = rightChildIndex;
      }
      if (minIndex !== index) {
        this.swap(index, minIndex);
        index = minIndex;
      } else {
        swapping = false;
      }
    }
  }
 
  swap(index1, index2) {
    const temp = this.heap[index1];
    this.heap[index1] = this.heap[index2];
    this.heap[index2] = temp;
  }
}
 
// Function to find maximum possible
// value after K given operations
function maxValue(arr, K) {
  // Stores required value
  let val = 0;
 
  // Initializing priority queue
  // with all elements of array
  const pq = new PriorityQueue((a, b) => b - a);
  arr.forEach((element) => pq.add(element));
 
  // Loop to iterate through
  // each operation
  while (K--) {
    // Current Maximum
    const max = pq.peek();
    pq.poll();
 
    // Update value
    val += max;
 
    // Reinsert maximum
    pq.add(Math.floor(max / 2));
  }
 
  // Return Answer
  return val;
}
 
// Driver Call
const arr = [2, 4, 6, 8, 10];
const K = 5;
document.write(maxValue(arr, K));


 
 

Output

33

 

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

 



Last Updated : 23 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads