Given an array arr[] consisting of N positive integers and an integer K, the task is to find the minimum possible array sum that can be obtained by repeatedly selecting a pair from the given array and divide one of the elements by 2 and multiply the other element by 2, at most K times.
Examples:
Input: arr[] = {5, 1, 10, 2, 3}, K = 1
Output: 17
Explanation:Since K = 1, the only operation is to update arr[1] = arr[1] * 2 and arr[2] = arr[2] / 2, which modifies arr[] = {5, 2, 5, 2, 3}. Therefore, the minimum possible sum of the array that can be obtained = 17.
Input: arr[] = {50, 1, 100, 100, 1}, K = 2
Output: 154
Explanation:
Operation 1: Updating arr[1] = arr[1] * 2 and arr[3] = arr[3] / 2 modifies arr[] = {50, 2, 100, 50, 1}.
Operation 2: Updating arr[4] = arr[4] * 2 and arr[2] = arr[2] / 2 modifies arr[] = {50, 2, 50, 50, 2}.
Therefore, the minimum possible sum of the array that can be obtained = 154.
Naive Approach: The simplest approach to solve the problem is to select the smallest and the largest array element for each operation and multiply the smallest array element by 2 and divide the largest array element by 2. Finally, after completing K operations, print the sum of all the array elements.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minimum_possible_sum( int arr[],
int n, int k)
{
if (n == 0) {
return 0;
}
if (n == 1) {
return arr[0];
}
for ( int i = 0; i < k; i++) {
int smallest_element
= arr[0];
int smallest_pos = 0;
int largest_element = arr[0];
int largest_pos = 0;
for ( int i = 1; i < n; i++) {
if (arr[i] >= largest_element) {
largest_element = arr[i];
largest_pos = i;
}
if (arr[i] < smallest_element) {
smallest_element = arr[i];
smallest_pos = i;
}
}
int a = smallest_element * 2;
int b = largest_element / 2;
if (a + b < smallest_element
+ largest_element) {
arr[smallest_pos] = a;
arr[largest_pos] = b;
}
}
int ans = 0;
for ( int i = 0; i < n; i++) {
ans += arr[i];
}
return ans;
}
int main()
{
int arr[] = { 50, 1, 100, 100, 1 };
int K = 2;
int n = sizeof (arr)
/ sizeof (arr[0]);
cout << minimum_possible_sum(
arr, n, K);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int minimum_possible_sum( int arr[],
int n, int k)
{
if (n == 0 )
{
return 0 ;
}
if (n == 1 )
{
return arr[ 0 ];
}
for ( int i = 0 ; i < k; i++)
{
int smallest_element = arr[ 0 ];
int smallest_pos = 0 ;
int largest_element = arr[ 0 ];
int largest_pos = 0 ;
for ( int j = 1 ; j < n; j++)
{
if (arr[j] >= largest_element)
{
largest_element = arr[j];
largest_pos = j;
}
if (arr[j] < smallest_element)
{
smallest_element = arr[j];
smallest_pos = j;
}
}
int a = smallest_element * 2 ;
int b = largest_element / 2 ;
if (a + b < smallest_element +
largest_element)
{
arr[smallest_pos] = a;
arr[largest_pos] = b;
}
}
int ans = 0 ;
for ( int i = 0 ; i < n; i++)
{
ans += arr[i];
}
return ans;
}
public static void main(String[] args)
{
int arr[] = { 50 , 1 , 100 , 100 , 1 };
int K = 2 ;
int n = arr.length;
System.out.print(minimum_possible_sum(
arr, n, K));
}
}
|
Python3
def minimum_possible_sum(arr, n, k):
if (n = = 0 ):
return 0
if (n = = 1 ):
return arr[ 0 ]
for i in range (k):
smallest_element = arr[ 0 ]
smallest_pos = 0
largest_element = arr[ 0 ]
largest_pos = 0
for i in range ( 1 , n):
if (arr[i] > =
largest_element):
largest_element = arr[i]
largest_pos = i
if (arr[i] <
smallest_element):
smallest_element = arr[i]
smallest_pos = i
a = smallest_element * 2
b = largest_element / / 2
if (a + b < smallest_element +
largest_element):
arr[smallest_pos] = a
arr[largest_pos] = b
ans = 0
for i in range (n):
ans + = arr[i]
return ans
if __name__ = = '__main__' :
arr = [ 50 , 1 , 100 , 100 , 1 ]
K = 2
n = len (arr)
print (minimum_possible_sum(arr, n, K))
|
C#
using System;
class GFG{
static int minimum_possible_sum( int [] arr,
int n, int k)
{
if (n == 0)
{
return 0;
}
if (n == 1)
{
return arr[0];
}
for ( int i = 0; i < k; i++)
{
int smallest_element = arr[0];
int smallest_pos = 0;
int largest_element = arr[0];
int largest_pos = 0;
for ( int j = 1; j < n; j++)
{
if (arr[j] >= largest_element)
{
largest_element = arr[j];
largest_pos = j;
}
if (arr[j] < smallest_element)
{
smallest_element = arr[j];
smallest_pos = j;
}
}
int a = smallest_element * 2;
int b = largest_element / 2;
if (a + b < smallest_element +
largest_element)
{
arr[smallest_pos] = a;
arr[largest_pos] = b;
}
}
int ans = 0;
for ( int i = 0; i < n; i++)
{
ans += arr[i];
}
return ans;
}
public static void Main()
{
int [] arr = { 50, 1, 100, 100, 1 };
int K = 2;
int n = arr.Length;
Console.WriteLine(minimum_possible_sum(
arr, n, K));
}
}
|
Javascript
<script>
function minimum_possible_sum(arr, n, k)
{
if (n == 0)
{
return 0;
}
if (n == 1)
{
return arr[0];
}
for (let i = 0; i < k; i++)
{
let smallest_element = arr[0];
let smallest_pos = 0;
let largest_element = arr[0];
let largest_pos = 0;
for (let j = 1; j < n; j++)
{
if (arr[j] >= largest_element)
{
largest_element = arr[j];
largest_pos = j;
}
if (arr[j] < smallest_element)
{
smallest_element = arr[j];
smallest_pos = j;
}
}
let a = smallest_element * 2;
let b = largest_element / 2;
if (a + b < smallest_element +
largest_element)
{
arr[smallest_pos] = a;
arr[largest_pos] = b;
}
}
let ans = 0;
for (let i = 0; i < n; i++)
{
ans += arr[i];
}
return ans;
}
let arr = [ 50, 1, 100, 100, 1 ];
let K = 2;
let n = arr.length;
document.write(minimum_possible_sum(
arr, n, K));
</script>
|
Time Complexity: O(K * N)
Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach the idea, is to use a balanced binary search tree. Follow the steps below to solve the problem:
- Create a multiset, say ms to store all the array elements in sorted order.
- Traverse the array and insert all array elements into ms.
- In each operation, find the smallest element, say smallest_element and the largest element, say largest_element in ms and update the value of smallest_element = smallest_element * 2 and largest_element = largest_element / 2.
- Finally, iterate over the multiset and print the sum of all the elements of ms.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minimum_possible_sum( int arr[],
int n, int k)
{
if (n == 0) {
return 0;
}
if (n == 1) {
return arr[0];
}
multiset< int > ms;
for ( int i = 0; i < n; i++) {
ms.insert(arr[i]);
}
for ( int i = 0; i < k; i++) {
int smallest_element
= *ms.begin();
int largest_element
= *ms.rbegin();
int a = smallest_element * 2;
int b = largest_element / 2;
if (a + b < smallest_element
+ largest_element) {
ms.erase(ms.begin());
ms.erase(prev(ms.end()));
ms.insert(a);
ms.insert(b);
}
}
int ans = 0;
for ( int x : ms) {
ans += x;
}
return ans;
}
int main()
{
int arr[] = { 50, 1, 100, 100, 1 };
int K = 2;
int n = sizeof (arr)
/ sizeof (arr[0]);
cout << minimum_possible_sum(
arr, n, K);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int minimum_possible_sum( int arr[],
int n, int k)
{
if (n == 0 )
{
return 0 ;
}
if (n == 1 )
{
return arr[ 0 ];
}
Vector<Integer> ms = new Vector<>();
for ( int i = 0 ; i < n; i++)
{
ms.add(arr[i]);
}
Collections.sort(ms);
for ( int i = 0 ; i < k; i++)
{
int smallest_element = ms.get( 0 );
int largest_element = ms.get(ms.size() - 1 );
int a = smallest_element * 2 ;
int b = largest_element / 2 ;
if (a + b < smallest_element +
largest_element)
{
ms.remove( 0 );
ms.remove(ms.size() - 1 );
ms.add(a);
ms.add(b);
Collections.sort(ms);
}
}
int ans = 0 ;
for ( int x : ms)
{
ans += x;
}
return ans;
}
public static void main(String[] args)
{
int arr[] = { 50 , 1 , 100 , 100 , 1 };
int K = 2 ;
int n = arr.length;
System.out.print(minimum_possible_sum(
arr, n, K));
}
}
|
Python3
def minimum_possible_sum(arr, n, k):
if (n = = 0 ):
return 0
if (n = = 1 ):
return arr[ 0 ]
ms = []
for i in range (n):
ms.append(arr[i])
ms.sort()
for i in range (k):
smallest_element = ms[ 0 ]
largest_element = ms[ - 1 ]
a = smallest_element * 2
b = largest_element / 2
if (a + b < smallest_element +
largest_element):
ms.pop( 0 )
ms.pop()
ms.append(a)
ms.append(b)
ms.sort()
ans = int ( sum (ms))
return ans
arr = [ 50 , 1 , 100 , 100 , 1 ]
K = 2
n = len (arr)
print (minimum_possible_sum(arr, n, K))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int minimum_possible_sum( int []arr,
int n, int k)
{
if (n == 0)
{
return 0;
}
if (n == 1)
{
return arr[0];
}
List< int > ms = new List< int >();
for ( int i = 0; i < n; i++)
{
ms.Add(arr[i]);
}
ms.Sort();
for ( int i = 0; i < k; i++)
{
int smallest_element = ms[0];
int largest_element = ms[ms.Count - 1];
int a = smallest_element * 2;
int b = largest_element / 2;
if (a + b < smallest_element +
largest_element)
{
ms.RemoveAt(0);
ms.RemoveAt(ms.Count - 1);
ms.Add(a);
ms.Add(b);
ms.Sort();
}
}
int ans = 0;
foreach ( int x in ms)
{
ans += x;
}
return ans;
}
public static void Main(String[] args)
{
int []arr = { 50, 1, 100, 100, 1 };
int K = 2;
int n = arr.Length;
Console.Write(minimum_possible_sum(
arr, n, K));
}
}
|
Javascript
<script>
function minimum_possible_sum(arr, n, k)
{
if (n == 0) {
return 0;
}
if (n == 1) {
return arr[0];
}
var ms = [];
for ( var i = 0; i < n; i++) {
ms.push(arr[i]);
}
ms.sort((a,b)=>a-b)
for ( var i = 0; i < k; i++) {
var smallest_element
= ms[0];
var largest_element
= ms[ms.length-1];
var a = smallest_element * 2;
var b = largest_element / 2;
if (a + b < smallest_element
+ largest_element) {
ms.shift();
ms.pop();
ms.push(a);
ms.push(b);
ms.sort((a,b)=>a-b)
}
}
var ans = 0;
ms.forEach(x => {
ans += x;
});
return ans;
}
var arr = [50, 1, 100, 100, 1];
var K = 2;
var n = arr.length;
document.write( minimum_possible_sum(
arr, n, K));
</script>
|
Time Complexity: O(K * log2N)
Auxiliary Space: O(1)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
02 Jun, 2021
Like Article
Save Article