Minimize array sum by replacing greater and smaller elements of pairs by half and double of their values respectively atmost K times
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)
Last Updated :
02 Jun, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...