Maximize sum possible by selecting K array elements followed by decrementing them by 1
Given an array arr[] consisting of N positive integers and an integer K. In one operation, select an array element, add it to the sum and then decrement it by 1. The task is to print the maximum sum that can be obtained by performing the operation K times.
Examples:
Input: arr[] = {2, 5}, K = 4
Output: 14
Explanation:
Perform the following operations to maximize the sum:
Operation 1: Select 5, then reduce it, so new array becomes {2, 4}.
Operation 2: Select 4, then reduce it, so new array becomes {2, 3}.
Operation 3: Select 3, then reduce it, so new array becomes {2, 2}.
Operation 4: Select 2, then reduce it, so new array becomes {2, 1}.
Therefore, the maximum sum is 5 + 4 + 3 + 2 = 14.
Input: arr[] = {2, 8, 4, 10, 6}, K = 2
Output: 19
Explanation:
Perform the following operations to maximize the sum:
Operation 1: Select 10, then reduce it, so new array becomes {2, 8, 4, 9, 6}.
Operation 2: Select 9, then reduce it, so new array becomes {2, 8, 4, 8, 6}.
Therefore, the maximum sum is 10 + 9 = 19.
Naive approach: The simplest approach is to use Max Heap to choose the maximum element each time. Add the maximum element to the sum and remove it from the Max Heap and add (maximum element – 1). Perform this operation K and print the sum.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
long maxSum(vector< int > arr, int k)
{
long max_sum = 0;
priority_queue< int > max_heap;
for ( int t : arr)
max_heap.push(t);
while (k-- > 0)
{
int tmp = max_heap.top();
max_heap.pop();
max_sum += tmp;
max_heap.push(tmp - 1);
}
return max_sum;
}
int main()
{
vector< int > arr = { 2, 5 };
int K = 4;
cout << maxSum(arr, K);
}
|
Java
import java.util.*;
class GFG {
public static long maxSum( int [] arr,
int k)
{
long max_sum = 0 ;
PriorityQueue<Integer> max_heap
= new PriorityQueue<>(
Collections.reverseOrder());
for ( int t : arr)
max_heap.add(t);
while (k-- > 0 ) {
int tmp = max_heap.poll();
max_sum += tmp;
max_heap.add(tmp - 1 );
}
return max_sum;
}
public static void main(String[] args)
{
int [] arr = { 2 , 5 };
int K = 4 ;
System.out.println(maxSum(arr, K));
}
}
|
Python3
from heapq import heappop, heappush, heapify
def maxSum(arr, k):
max_sum = 0
max_heap = []
heapify(max_heap)
for i in range ( len (arr) - 1 , 0 , - 1 ):
heappush(max_heap, arr[i])
while (k > 0 ):
tmp = heappop(max_heap)
max_sum + = tmp
heappush(max_heap, tmp - 1 )
k - = 1
return max_sum
if __name__ = = '__main__' :
arr = [ 2 , 5 ]
K = 4
print (maxSum(arr, K))
|
C#
using System;
using System.Collections.Generic;
class GFG{
public static long maxSum( int [] arr, int k)
{
long max_sum = 0;
List< int > max_heap = new List< int >();
foreach ( int t in arr) max_heap.Add(t);
max_heap.Sort();
max_heap.Reverse();
while (k-- > 1)
{
int tmp = max_heap[0];
max_heap.Remove(0);
max_sum += tmp;
max_heap.Add(tmp - 1);
max_heap.Sort();
max_heap.Reverse();
}
return max_sum - 1;
}
public static void Main(String[] args)
{
int [] arr = { 2, 5 };
int K = 4;
Console.WriteLine(maxSum(arr, K));
}
}
|
Javascript
<script>
function maxSum(arr, k)
{
let max_sum = 0;
let max_heap = [];
for (let t = 0; t < arr.length; t++)
max_heap.push(arr[t]);
max_heap.sort( function (a, b){ return b - a;});
while (k-- > 0)
{
let tmp = max_heap.shift();
max_sum += tmp;
max_heap.push(tmp - 1);
max_heap.sort( function (a, b){ return b - a;});
}
return max_sum;
}
let arr = [ 2, 5 ];
let K = 4;
document.write(maxSum(arr, K));
</script>
|
Time Complexity: O(K*log(N)), where N is the length of the given array and K is the given number of operations.
Auxiliary Space: O(N)
Efficient Approach: The idea is to use the Hashing concept by storing the frequency of each element of the given array. Follow the below steps to solve the problem:
- Create freq[] of size M + 1 where M is the maximum element present in the given array and a variable max_sum to store the frequency of each element of arr[] and maximum possible sum respectively.
- Traverse the array freq[] from right to left i.e., from i = M to 0.
- Increment max_sum by freq[i]*i, reduce K by freq[i] and increment freq[i – 1] by freq[i], if K ? freq[i].
- Else increment max_sum by i*K and break the loop because K becomes 0.
- Return max_sum as the maximum possible sum.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
long maxSum( int arr[], int k, int n)
{
long max_sum = 0;
int freq[100000 + 1] = {0};
for ( int i = 0; i < n; i++)
freq[arr[i]]++;
for ( int i = 100000; i > 0; i--)
{
if (k >= freq[i])
{
max_sum += i * freq[i];
k -= freq[i];
freq[i - 1] += freq[i];
}
else
{
max_sum += i * k;
break ;
}
}
return max_sum;
}
int main()
{
int arr[] = { 2, 5 };
int n = sizeof (arr) / sizeof (arr[0]);
int K = 4;
cout << (maxSum(arr, K, n));
return 0;
}
|
Java
import java.util.*;
class GFG {
public static long maxSum( int [] arr,
int k)
{
long max_sum = 0 ;
int [] freq = new int [ 100000 + 1 ];
for ( int t : arr)
freq[t]++;
for ( int i = 100000 ; i > 0 ; i--) {
if (k >= freq[i]) {
max_sum += i * freq[i];
k -= freq[i];
freq[i - 1 ] += freq[i];
}
else {
max_sum += i * k;
break ;
}
}
return max_sum;
}
public static void main(String[] args)
{
int [] arr = { 2 , 5 };
int K = 4 ;
System.out.println(maxSum(arr, K));
}
}
|
Python3
def maxSum(arr, k):
max_sum = 0 ;
freq = [ 0 ] * ( 100000 + 1 );
for i in range ( len (arr)):
freq[arr[i]] + = 1 ;
for i in range ( 100000 , 1 , - 1 ):
if (k > = freq[i]):
max_sum + = i * freq[i];
k - = freq[i];
freq[i - 1 ] + = freq[i];
else :
max_sum + = i * k;
break ;
return max_sum;
if __name__ = = '__main__' :
arr = [ 2 , 5 ];
K = 4 ;
print (maxSum(arr, K));
|
C#
using System;
class GFG{
public static long maxSum( int [] arr,
int k)
{
long max_sum = 0;
int [] freq =
new int [100000 + 1];
foreach ( int t in arr)
{
freq[t]++;
}
for ( int i = 100000; i > 0; i--)
{
if (k >= freq[i])
{
max_sum += i * freq[i];
k -= freq[i];
freq[i - 1] += freq[i];
}
else
{
max_sum += i * k;
break ;
}
}
return max_sum;
}
public static void Main(String[] args)
{
int [] arr = {2, 5};
int K = 4;
Console.WriteLine(
maxSum(arr, K));
}
}
|
Javascript
<script>
function maxSum(arr, k, n)
{
var max_sum = 0;
var freq = new Array(100000 + 1);
freq.fill(0);
for ( var i = 0; i < n; i++)
freq[arr[i]]++;
for ( var i = 100000; i > 0; i--)
{
if (k >= freq[i])
{
max_sum += i * freq[i];
k -= freq[i];
freq[i - 1] += freq[i];
}
else
{
max_sum += i * k;
break ;
}
}
return max_sum;
}
var arr = [ 2, 5 ];
var n = arr.length;
var K = 4;
document.write (maxSum(arr, K, n));
</script>
|
Time Complexity: O(N), where N is the length of the given array.
Auxiliary Space: O(max(arr)) as we took freq hashmap of size equal to maximum element of the given array.
This solution would be better to use when size(array) and maximum(array) are of same order.
Last Updated :
03 May, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...