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 become {2, 4}.
Operation 2: Select 4, then reduce it so new array become {2, 3}.
Operation 3: Select 3, then reduce it so new array become {2, 2}.
Operation 4: Select 2, then reduce it so new array become {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 become {2, 8, 4, 9, 6}.
Operation 2: Select 9, then reduce it so new array become {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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find maximum possible
// after adding elements K times and
// decrementing each added value by 1
long maxSum(vector<int> arr, int k)
{
     
    // Stores the maximum sum
    long max_sum = 0;
 
    // Create max_heap to get
    // the maximum element
    priority_queue<int> max_heap;
 
    // Update the max_heap
    for(int t : arr)
        max_heap.push(t);
 
    // Calculate the max_sum
    while (k-- > 0)
    {
        int tmp = max_heap.top();
        max_heap.pop();
        max_sum += tmp;
        max_heap.push(tmp - 1);
    }
 
    // Return the maximum sum
    return max_sum;
}
 
// Driver code
int main()
{
     
    // Given an array arr[]
    vector<int> arr = { 2, 5 };
     
    // Given K
    int K = 4;
     
    // Function Call
    cout << maxSum(arr, K);
}
 
// This code is contributed by mohit kumar 29

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
import java.util.*;
 
class GFG {
 
    // Function to find maximum possible
    // after adding elements K times and
    // decrementing each added value by 1
    public static long maxSum(int[] arr,
                              int k)
    {
        // Stores the maximum sum
        long max_sum = 0;
 
        // Create max_heap to get
        // the maximum element
        PriorityQueue<Integer> max_heap
            = new PriorityQueue<>(
                Collections.reverseOrder());
 
        // Update the max_heap
        for (int t : arr)
            max_heap.add(t);
 
        // Calculate the max_sum
        while (k-- > 0) {
            int tmp = max_heap.poll();
            max_sum += tmp;
            max_heap.add(tmp - 1);
        }
 
        // Return the maximum sum
        return max_sum;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Given an array arr[]
        int[] arr = { 2, 5 };
 
        // Given K
        int K = 4;
 
        // Function Call
        System.out.println(maxSum(arr, K));
    }
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for the above approach
 
# Function to find maximum possible
# after adding elements K times and
# decrementing each added value by 1
from heapq import heappop, heappush, heapify
 
def maxSum(arr, k):
     
    # Stores the maximum sum
    max_sum = 0
 
    # Create max_heap to get
    # the maximum element
    max_heap = []
    heapify(max_heap)
 
    # Update the max_heap
    for i in range(len(arr) - 1, 0, -1):
        heappush(max_heap, arr[i])
         
    # Calculate the max_sum
    while (k > 0):
        tmp = heappop(max_heap)
        max_sum += tmp
        #max_heap.put(tmp - 1);
        heappush(max_heap, tmp - 1)
        k -= 1
 
    # Return the maximum sum
    return max_sum
 
# Driver Code
if __name__ == '__main__':
     
    # Given an array arr
    arr = [ 2, 5 ]
 
    # Given K
    K = 4
 
    # Function Call
    print(maxSum(arr, K))
 
# This code is contributed by gauravrajput1

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the
// above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to find maximum possible
// after adding elements K times and
// decrementing each added value by 1
public static long maxSum(int[] arr, int k)
{
     
    // Stores the maximum sum
    long max_sum = 0;
 
    // Create max_heap to get
    // the maximum element
    List<int> max_heap = new List<int>();
 
    // Update the max_heap
    foreach(int t in arr) max_heap.Add(t);
    max_heap.Sort();
    max_heap.Reverse();
     
    // Calculate the max_sum
    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 the maximum sum
    return max_sum - 1;
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given an array []arr
    int[] arr = { 2, 5 };
     
    // Given K
    int K = 4;
 
    // Function Call
    Console.WriteLine(maxSum(arr, K));
}
}
 
// This code is contributed by gauravrajput1

chevron_right


Output: 

14

 

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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find maximum possible
// after adding elements K times and
// decrementing each added value by 1
long maxSum(int arr[], int k, int n)
{
     
    // Stores the maximum sum
    long max_sum = 0;
 
    // Stores freqency of element
    int freq[100000 + 1] = {0};
 
    // Update freqency of array element
    for(int i = 0; i < n; i++)
        freq[arr[i]]++;
 
    // Traverse from right to left in
    // freq[] to find maximum sum
    for(int i = 100000; i > 0; i--)
    {
        if (k >= freq[i])
        {
             
            // Update max_sum
            max_sum += i * freq[i];
 
            // Decrement k
            k -= freq[i];
            freq[i - 1] += freq[i];
        }
 
        // Update max_sum and break
        else
        {
            max_sum += i * k;
            break;
        }
    }
 
    // Return the maximum sum
    return max_sum;
}
 
// Driver Code
int main()
{
     
    // Given array arr[]
    int arr[] = { 2, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Given K
    int K = 4;
 
    // Function Call
    cout << (maxSum(arr, K, n));
    return 0;
}
 
// This code is contributed by chitranayal

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
import java.util.*;
 
class GFG {
 
    // Function to find maximum possible
    // after adding elements K times and
    // decrementing each added value by 1
    public static long maxSum(int[] arr,
                              int k)
    {
        // Stores the maximum sum
        long max_sum = 0;
 
        // Stores freqency of element
        int[] freq = new int[100000 + 1];
 
        // Update freqency of array element
        for (int t : arr)
            freq[t]++;
 
        // Traverse from right to left in
        // freq[] to find maximum sum
        for (int i = 100000; i > 0; i--) {
 
            if (k >= freq[i]) {
 
                // Update max_sum
                max_sum += i * freq[i];
 
                // Decrement k
                k -= freq[i];
                freq[i - 1] += freq[i];
            }
 
            // Update max_sum and break
            else {
                max_sum += i * k;
                break;
            }
        }
 
        // Return the maximum sum
        return max_sum;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Given array arr[]
        int[] arr = { 2, 5 };
 
        // Given K
        int K = 4;
 
        // Function Call
        System.out.println(maxSum(arr, K));
    }
}

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the
// above approach
using System;
class GFG{
 
// Function to find maximum possible
// after adding elements K times and
// decrementing each added value by 1
public static long maxSum(int[] arr,
                          int k)
{
  // Stores the maximum
  // sum
  long max_sum = 0;
 
  // Stores freqency of
  // element
  int[] freq =
        new int[100000 + 1];
 
  // Update freqency of
  // array element
  foreach (int t in arr)
  {
    freq[t]++;
  }
 
  // Traverse from right to
  // left in []freq to find
  // maximum sum
  for (int i = 100000; i > 0; i--)
  {
    if (k >= freq[i])
    {
      // Update max_sum
      max_sum += i * freq[i];
 
      // Decrement k
      k -= freq[i];
      freq[i - 1] += freq[i];
    }
 
    // Update max_sum and
    // break
    else
    {
      max_sum += i * k;
      break;
    }
  }
 
  // Return the maximum
  // sum
  return max_sum;
}
 
// Driver Code
public static void Main(String[] args)
{
  // Given array []arr
  int[] arr = {2, 5};
 
  // Given K
  int K = 4;
 
  // Function Call
  Console.WriteLine(
  maxSum(arr, K));
}
}
 
// This code is contributed by gauravrajput1

chevron_right


Output: 

14

 

Time Complexity: O(N), where N is the length of the given array.
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.