Open In App
Related Articles

Minimize Sum of an Array by at most K reductions

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Report issue
Report

Given an array of integers arr[] consisting of N integers, the task is to minimize the sum of the given array by performing at most K operations, where each operation involves reducing an array element arr[i] to floor(arr[i]/2).

Examples :

Input: N = 4, a[] = {20, 7, 5, 4}, K = 3 
Output: 17 
Explanation: 
Operation 1: {20, 7, 5, 4} -> {10, 7, 5, 4} 
Operation 2: {10, 7, 5, 4} -> {5, 7, 5, 4} 
Operation 3: {5, 7, 5, 4} -> {5, 3, 5, 4} 
No further operation can be performed. Therefore, sum of the array = 17.

Input: N = 4, a[] = {10, 4, 6, 16}, K = 2 
Output: 23

Approach: To obtain the minimum possible sum, the main idea for every operation is to reduce the maximum element in the array before each operation. This can be implemented using MaxHeap. Follow the steps below to solve the problem:

  • Insert all the array elements into MaxHeap.
  • Pop the root of the MaxHeap and insert (popped element) / 2 into the MaxHeap
  • After repeating the above step K times, pop the elements of the MaxHeap one by one and keep adding their values. Finally, print the sum.

Below is the implementation of above approach:

C++

// C++ program to implement the
// above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to obtain the minimum possible
// sum from the array by K reductions
int minSum(int a[], int n, int k)
{
    priority_queue <int> q;
     
    // Insert elements into the MaxHeap
    for(int i = 0; i < n; i++)
    {
        q.push(a[i]);
    }
     
    while(!q.empty() && k > 0)
    {
        int top = q.top() / 2;
         
        // Remove the maximum            
        q.pop();
         
        // Insert maximum / 2
        q.push(top);
        k -= 1;
    }
     
    // Stores the sum of remaining elements
    int sum = 0;
    while(!q.empty())
    {
        sum += q.top();
        q.pop();
    }
    return sum;
}
 
// Driver code
int main()
{
    int n = 4;
    int k = 3;
    int a[] = { 20, 7, 5, 4 };
         
    cout << (minSum(a, n, k));
     
    return 0;
}
 
// This code is contributed by jojo9911

                    

Java

// Java Program to implement the
// above approach
import java.io.*;
import java.util.*;
class GFG {
 
    // Function to obtain the minimum possible
    // sum from the array by K reductions
    public static int minSum(int a[], int n, int k)
    {
        // Implements the MaxHeap
        PriorityQueue<Integer> maxheap
            = new PriorityQueue<>((one, two) -> two - one);
 
        // Insert elements into the MaxHeap
        for (int i = 0; i < n; i++)
            maxheap.add(a[i]);
 
        while (maxheap.size() > 0 && k > 0) {
 
            // Remove the maximum
            int max_ele = maxheap.poll();
 
            // Insert maximum / 2
            maxheap.add(max_ele / 2);
            k -= 1;
        }
 
        // Stores the sum of remaining elements
 
        int sum = 0;
        while (maxheap.size() > 0)
            sum += maxheap.poll();
 
        return sum;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int n = 4;
        int k = 3;
        int a[] = { 20, 7, 5, 4 };
        System.out.println(minSum(a, n, k));
    }
}

                    

Python3

# Python3 program to implement the
# above approach
 
# Function to obtain the minimum possible
# sum from the array by K reductions
def minSum(a, n, k):
     
    q = []
     
    # Insert elements into the MaxHeap
    for i in range(n):
        q.append(a[i])
         
    q = sorted(q)   
 
    while (len(q) > 0 and k > 0):
        top = q[-1] // 2
 
        # Remove the maximum
        del q[-1]
 
        # Insert maximum / 2
        q.append(top)
        k -= 1
        q = sorted(q)
 
    # Stores the sum of remaining elements
    sum = 0
    while(len(q) > 0):
        sum += q[-1]
        del q[-1]
         
    return sum
 
# Driver code
if __name__ == '__main__':
     
    n = 4
    k = 3
     
    a = [ 20, 7, 5, 4 ]
 
    print(minSum(a, n, k))
 
# This code is contributed by mohit kumar 29

                    

C#

// C# program to implement the
// above approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// Function to obtain the minimum possible
// sum from the array by K reductions
static int minSum(int[] a, int n, int k)
{
     
    // Implements the MaxHeap
    List<int> q = new List<int>();
    for(int i = 0; i < n; i++)
    {
         
        // Insert elements into the MaxHeap
        q.Add(a[i]);
    }
     
    q.Sort();
    while (q.Count != 0 && k > 0)
    {
        int top = q[q.Count - 1] / 2;
         
        // Remove the maximum
        // Insert maximum / 2
        q[q.Count - 1] = top;
         
        k--;
        q.Sort();
    }
     
    // Stores the sum of remaining elements
    int sum = 0;
    while (q.Count != 0)
    {
        sum += q[0];
        q.RemoveAt(0);
    }
    return sum;
}
 
// Driver Code
static public void Main()
{
    int n = 4;
    int k = 3;
    int[] a = { 20, 7, 5, 4 };
     
    Console.WriteLine(minSum(a, n, k));
}
}
 
// This code is contributed by avanitrachhadiya2155

                    

Javascript

<script>
// Javascript Program to implement the
// above approach
 
// Function to obtain the minimum possible
    // sum from the array by K reductions
function  minSum(a,n,k)
{
    // Implements the MaxHeap
        let maxheap = [];
  
        // Insert elements into the MaxHeap
        for (let i = 0; i < n; i++)
            maxheap.push(a[i]);
          
        maxheap.sort(function(a,b){return a-b;});
         
        while (maxheap.length > 0 && k > 0) {
  
            // Remove the maximum
            let max_ele = maxheap.pop();
  
            // Insert maximum / 2
            maxheap.push(Math.floor(max_ele / 2));
            k -= 1;
            maxheap.sort(function(a,b){return a-b;});
        }
  
        // Stores the sum of remaining elements
  
        let sum = 0;
        while (maxheap.length > 0)
            sum += maxheap.shift();
  
        return sum;
}
 
// Driver Code
let n = 4;
let k = 3;
let a = [ 20, 7, 5, 4 ];
document.write(minSum(a, n, k));
 
// This code is contributed by unknown2108
</script>

                    

Output
17

Time Complexity: O(Klog(N)) 
Auxiliary Space: O(N)

Other approach: By using a queue

  • make a empty double ended queue
  • sort the array
  • pick max element from comparing front element from queue and last element from array
  • insert (popped element) / 2 into the end of the queue
  • repeat the process k times

Examples :

Input: N = 4, a[] = {20, 7, 5, 4}, K = 3 
Output: 17 
Explanation: 

sorted array =a[] = {4 , 5, 7 ,20}

queue = []
Operation 1: pop max from array and insert in queue then array becomes , a[] = { 4 , 5,7} , queue = [10]

Operation 2: compare max from array and rear from queue which is greater and append at the end of the queue max of array = 7 font of queue = 10 rear of queue is greater append  element at the queue and remove the rear element. a[] = { 4 , 5, ,7}  , queue = [5]
Operation 3:compare max from array and rear from queue which is greater and append at the end of the queue max of array = 7  font of queue = 5  , max  element from the array is greater  and remove the max element from array and append to the queue. a[] = { 4 , 5 }  , queue = [5 , 3]
No further operation can be performed. Therefore, sum of the array  and queue = 17

Input: N = 4, a[] = {10, 4, 6, 16}, K = 2 
Output: 23

C++

#include <bits/stdc++.h>
using namespace std;
 
// Function to obtain the minimum possible
// sum from the array by K reductions
int minSum(vector<int>& a, int n, int k)
{
    // Sort the array in ascending order
    sort(a.begin(), a.end());
    // Create a queue
    queue<int> queue;
    while (k > 0) {
        // If queue is empty, append the max element of
        // array
        if (queue.empty()) {
            int temp = a.back();
            // Delete the max element from array
            a.pop_back();
            // Append the max element to queue
            queue.push(temp / 2);
            // Decrement k
            k = k - 1;
        }
        else {
            int temp = a.back();
            // If rear is greater than max, append the rear
            // element
            if (queue.front() > temp) {
                // Pop the rear element from queue
                temp = queue.front();
                queue.pop();
                queue.push(temp / 2);
            }
            else {
                a.pop_back();
                queue.push(temp / 2);
            }
            k = k - 1;
        }
    }
    // Stores the sum of remaining elements
    int sum = 0;
    while (!queue.empty()) {
        sum += queue.front();
        queue.pop();
    }
    for (int i = 0; i < a.size(); i++) {
        sum += a[i];
    }
    return sum;
}
 
// Driver code
int main()
{
    int n = 4;
    int k = 3;
    vector<int> a{ 20, 7, 5, 4 };
    cout << minSum(a, n, k) << endl;
 
    int N = 4;
    vector<int> A{ 10, 4, 6, 16 };
    int K = 2;
    cout << minSum(A, N, K) << endl;
    return 0;
}
// This code is contributed by sarojmcy2e

                    

Java

// java program to implement the above approach
import java.util.*;
 
public class Main {
    public static int minSum(List<Integer> a, int k)
    {
        // Sort the array in ascending order
        Collections.sort(a);
        // Create a queue
        Queue<Integer> queue = new LinkedList<>();
        while (k > 0) {
            // If queue is empty, append the max element of
            // array
            if (queue.isEmpty()) {
                int temp = a.get(a.size() - 1);
                // Delete the max element from array
                a.remove(a.size() - 1);
                // Append the max element to queue
                queue.offer(temp / 2);
                // Decrement k
                k = k - 1;
            }
            else {
                int temp = a.get(a.size() - 1);
                // If rear is greater than max, append the
                // rear element
                if (queue.peek() > temp) {
                    // Pop the rear element from queue
                    temp = queue.poll();
                    queue.offer(temp / 2);
                }
                else {
                    a.remove(a.size() - 1);
                    queue.offer(temp / 2);
                }
                k = k - 1;
            }
        }
        // Stores the sum of remaining elements
        int sum = 0;
        while (!queue.isEmpty()) {
            sum += queue.poll();
        }
        for (int i = 0; i < a.size(); i++) {
            sum += a.get(i);
        }
        return sum;
    }
 
    public static void main(String[] args)
    {
        List<Integer> a = new ArrayList<>();
        a.add(20);
        a.add(7);
        a.add(5);
        a.add(4);
        int k = 3;
        System.out.println(minSum(a, k));
 
        List<Integer> A = new ArrayList<>();
        A.add(10);
        A.add(4);
        A.add(6);
        A.add(16);
        int K = 2;
        System.out.println(minSum(A, K));
    }
}
// this code is implemented by Chetan Bargal

                    

Python3

# Python3 program to implement the
# above approach
 
# Function to obtain the minimum possible
# sum from the array by K reductions
 
 
def minSum(a, n, k):
    a.sort()
    # Create a queue
    queue = []
    while k > 0:
        # if queue is empty append the max element of array
        if len(queue) == 0:
            temp = a[-1]
            # del the max element from array
            del a[-1]
            # append the max element to queue
            queue.append(temp // 2)
            # decrement the k
            k = k - 1
            # Insert maximum / 2
        else:
            # store max element to temp
            temp = a[-1]
            # if rear is greater than max
            # append the rear element
            if queue[0] > temp:
              # pop the rear element from queue
                temp = queue.pop(0)
                queue.append(temp // 2)
            else:
                del a[-1]
                queue.append(temp // 2)
            k = k - 1
    # Stores the sum of remaining elements
    return sum(queue) + sum(a)
 
 
# Driver code
if __name__ == '__main__':
 
    n = 4
    k = 3
 
    a = [20, 7, 5, 4]
 
    print(minSum(a, n, k))
     
    N = 4
    A =  [10, 4, 6, 16 ]
    K = 2
    print(minSum(A, N, K))
 
# This code is Contributed by Shushant Kumar

                    

C#

using System;
using System.Collections.Generic;
using System.Linq;
 
class Program {
    // Function to obtain the minimum possible
    // sum from the array by K reductions
    static int MinSum(List<int> a, int n, int k)
    {
        // Sort the array in ascending order
        a.Sort();
        // Create a queue
        Queue<int> queue = new Queue<int>();
        while (k > 0) {
            // If queue is empty, append the max element of
            // array
            if (queue.Count == 0) {
                int temp = a.Last();
                // Delete the max element from array
                a.RemoveAt(a.Count - 1);
                // Append the max element to queue
                queue.Enqueue(temp / 2);
                // Decrement k
                k = k - 1;
            }
            else {
                int temp = a.Last();
                // If rear is greater than max, append the
                // rear element
                if (queue.Peek() > temp) {
                    // Pop the rear element from queue
                    temp = queue.Dequeue();
                    queue.Enqueue(temp / 2);
                }
                else {
                    a.RemoveAt(a.Count - 1);
                    queue.Enqueue(temp / 2);
                }
                k = k - 1;
            }
        }
        // Stores the sum of remaining elements
        int sum = 0;
        while (queue.Count != 0) {
            sum += queue.Dequeue();
        }
        for (int i = 0; i < a.Count; i++) {
            sum += a[i];
        }
        return sum;
    }
 
    static void Main(string[] args)
    {
        int n = 4;
        int k = 3;
        List<int> a = new List<int>{ 20, 7, 5, 4 };
        Console.WriteLine(MinSum(a, n, k));
 
        int N = 4;
        List<int> A = new List<int>{ 10, 4, 6, 16 };
        int K = 2;
        Console.WriteLine(MinSum(A, N, K));
    }
}
// This code is contributed by user_dtewbxkn77n

                    

Javascript

// Function to obtain the minimum possible
// sum from the array by K reductions
function minSum(a, n, k)
{
 
    // Sort the array in ascending order
    a.sort((x, y) => x - y);
 
    // Create a queue
    const queue = [];
 
    while (k > 0) {
        // If queue is empty, append the max element of array
        if (queue.length === 0) {
            const temp = a.pop();
            // Append the max element to queue
            queue.push(Math.floor(temp / 2));
            // Decrement k
            k = k - 1;
        } else {
            const temp = a.pop();
            // If rear is greater than max, append the rear element
            if (queue[0] > temp) {
                // Pop the rear element from queue
                const rear = queue.shift();
                queue.push(Math.floor(temp / 2));
                a.push(rear);
            } else {
                queue.push(Math.floor(temp / 2));
            }
            k = k - 1;
        }
    }
 
    // Stores the sum of remaining elements
    let sum = 0;
    for (let i = 0; i < a.length; i++) {
        sum += a[i];
    }
    while (queue.length > 0) {
        sum += queue.shift();
    }
    return sum;
}
 
// Driver code
const n = 4;
const k = 3;
const a = [20, 7, 5, 4];
console.log(minSum(a, n, k)); // Output: 17
 
const N = 4;
const A = [10, 4, 6, 16];
const K = 2;
console.log(minSum(A, N, K)); // Output: 23

                    

Output
17
23

Time Complexity: O(k + Nlog(N))  : Nlog(N) for sorting
Auxiliary Space: O(N)  :  for making a queue



Last Updated : 07 Jan, 2024
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads