Open In App

Maximize Array sum after incrementing at most K elements followed by dividing array by X

Last Updated : 25 Nov, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array, arr[] and two integers, K and X, the task is to maximize the sum of the array elements after at most K increments of any elements, then dividing all of the elements by X

Example:

Input: arr = {16, 15, 17}, K = 8, X = 10
Output: 5
Explanation: At most 8 increments are allowed. So, increment element at index 0 by 4 and element at index 2 by 3. So the modified array becomes {20/10, 15/10, 20/10} = {2, 1, 2}, therefore the sum is 2+1+2 = 5

Input: arr = {8, 13, 2, 4, 7}, K = 6, X = 5
Output: 7

 

Approach: The given problem can be solved by using a greedy approach. The idea is to sort the array by tweaking the comparator in such a way that the elements which need the least increment to become divisible by X are encountered first. Follow the steps below to solve the problem:

  • Sort the ArrayList in the order where elements having the greater remainder after dividing by X are encountered first
  • Iterate the ArrayList and at every iteration:
    • Find the remaining value rem to be added to arr[i], such that it becomes a multiple of X
      • If K < rem, then break the loop
      • Else increment arr[i] with rem and decrement K by rem
  • Initialize a variable sum to 0
  • Traverse the ArrayList and at every iteration:
    • Add arr[i] / X to the sum

Below is the implementation of the above approach:

C++




// C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
int x = 5;
static bool cmp(int a, int b) { return (b % x) < (a % x); }
 
int maxSumIncDiv(vector<int> nums, int k)
{
 
    // Sort in such a way that the
    // numbers needing least increment
    // to become multiple of x are
    // encountered first
    sort(nums.begin(), nums.end(), cmp);
    // Iterate the ArrayList
    for (int i = 0; i < nums.size(); i++) {
 
        int rem = nums[i] % x;
 
        // Find the value to increment
        // current element such that it
        // becomes a multiple of x
        rem = x - rem;
 
        // Incrementing any element with
        // the remaining value of k will
        // have no effect
        if (k < rem) {
 
            break;
        }
        else {
 
            // Increment element so that
            // it becomes multiple of x
            nums[i] = nums[i] + rem;
 
            // Decrement k by the
            // remaining value
            k -= rem;
        }
    }
 
    // Initialize sum
    int sum = 0;
 
    // Traverse the ArrayList
    for (int i = 0; i < nums.size(); i++) {
 
        // calculate sum of elements
        // divided by x
        sum += nums[i] / x;
    }
 
    // Return the answer
    return sum;
}
 
int main()
{
 
    // Initializing list of nums
    vector<int> nums = { 8, 13, 2, 4, 7 };
 
    int K = 6;
 
    // Call the function and
    // print the answer
    cout << (maxSumIncDiv(nums, K));
    return 0;
}
 
// This code is contributed by Potta Lokesh


Java




// Java implementation for the above approach
 
import java.util.*;
import java.io.*;
 
class GFG {
    public static int maxSumIncDiv(
        List<Integer> nums, int k, int x)
    {
 
        // Sort in such a way that the
        // numbers needing least increment
        // to become multiple of x are
        // encountered first
        Collections.sort(
            nums,
            (a, b) -> b % x - a % x);
 
        // Iterate the ArrayList
        for (int i = 0; i < nums.size(); i++) {
 
            int rem = nums.get(i) % x;
 
            // Find the value to increment
            // current element such that it
            // becomes a multiple of x
            rem = x - rem;
 
            // Incrementing any element with
            // the remaining value of k will
            // have no effect
            if (k < rem) {
 
                break;
            }
            else {
 
                // Increment element so that
                // it becomes multiple of x
                nums.set(i, nums.get(i) + rem);
 
                // Decrement k by the
                // remaining value
                k -= rem;
            }
        }
 
        // Initialize sum
        int sum = 0;
 
        // Traverse the ArrayList
        for (int i = 0; i < nums.size(); i++) {
 
            // calculate sum of elements
            // divided by x
            sum += nums.get(i) / x;
        }
 
        // Return the answer
        return sum;
    }
    public static void main(String[] args)
    {
 
        // Initializing list of nums
        List<Integer> nums = new ArrayList<>();
 
        int K = 6, X = 5;
        nums.add(8);
        nums.add(13);
        nums.add(2);
        nums.add(4);
        nums.add(7);
 
        // Call the function and
        // print the answer
        System.out.println(
            maxSumIncDiv(nums, K, X));
    }
}


Python3




# Python implementation for the above approach
import math
 
def maxSumIncDiv(nums, k, x):
 
  # Sort in such a way that the
  # numbers needing least increment
  # to become multiple of x are
  # encountered first
  nums.sort();
 
  # Iterate the ArrayList
  for i in range(len(nums)):
 
      rem = nums[i] % x;
 
      # Find the value to increment
      # current element such that it
      # becomes a multiple of x
      rem = x - rem;
 
      # Incrementing any element with
      # the remaining value of k will
      # have no effect
      if (k < rem):
        break;
      else:
 
        # Increment element so that
        # it becomes multiple of x
        nums[i] = nums[i] + rem;
 
        # Decrement k by the
        # remaining value
        k -= rem;
 
  # Initialize sum
  sum = 0;
 
  # Traverse the ArrayList
  for i in range(len(nums)):
 
    # calculate sum of elements
    # divided by x
    sum += nums[i] / x;
 
  # Return the answer
  return math.floor(sum)
     
# Initializing list of nums
nums = [];
K = 6
X = 5
nums.append(8);
nums.append(13);
nums.append(2);
nums.append(4);
nums.append(7);
 
# Call the function and
# print the answer
print(maxSumIncDiv(nums, K, X));
     
# This code is contributed by gfgking.


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG
{
    public static int maxSumIncDiv(
        List<int> nums, int k, int x)
    {
 
        // Sort in such a way that the
        // numbers needing least increment
        // to become multiple of x are
        // encountered first
        nums.Sort((a, b) => b % x - a % x);
 
        // Iterate the ArrayList
        for (int i = 0; i < nums.Count; i++) {
 
            int rem = nums[i] % x;
 
            // Find the value to increment
            // current element such that it
            // becomes a multiple of x
            rem = x - rem;
 
            // Incrementing any element with
            // the remaining value of k will
            // have no effect
            if (k < rem) {
 
                break;
            }
            else {
 
                // Increment element so that
                // it becomes multiple of x
                nums[i] = nums[i] + rem;
 
                // Decrement k by the
                // remaining value
                k -= rem;
            }
        }
 
        // Initialize sum
        int sum = 0;
 
        // Traverse the ArrayList
        for (int i = 0; i < nums.Count; i++) {
 
            // calculate sum of elements
            // divided by x
            sum += nums[i] / x;
        }
 
        // Return the answer
        return (sum);
    }
 
// Driver Code
public static void Main(String[] args)
{
   
    // Initializing list of nums
        List<int> nums = new List<int>();
 
        int K = 6, X = 5;
        nums.Add(8);
        nums.Add(13);
        nums.Add(2);
        nums.Add(4);
        nums.Add(7);
 
        // Call the function and
        // print the answer
        Console.Write(
            maxSumIncDiv(nums, K, X));
}
}
 
// This code is contributed by code_hunt.


Javascript




<script>
 
// Javascript implementation for the above approach
 
function maxSumIncDiv(nums, k, x)
    {
 
        // Sort in such a way that the
        // numbers needing least increment
        // to become multiple of x are
        // encountered first
        nums.sort((a, b) => b % x - a % x);
 
        // Iterate the ArrayList
        for (var i = 0; i < nums.length; i++) {
 
            var rem = nums[i] % x;
 
            // Find the value to increment
            // current element such that it
            // becomes a multiple of x
            rem = x - rem;
 
            // Incrementing any element with
            // the remaining value of k will
            // have no effect
            if (k < rem) {
 
                break;
            }
            else {
 
                // Increment element so that
                // it becomes multiple of x
                nums[i] = nums[i] + rem;
 
                // Decrement k by the
                // remaining value
                k -= rem;
            }
        }
 
        // Initialize sum
        var sum = 0;
 
        // Traverse the ArrayList
        for (var i = 0; i < nums.length; i++) {
 
            // calculate sum of elements
            // divided by x
            sum += nums[i] / x;
        }
 
        // Return the answer
        return parseInt(sum);
    }
 
 
// Initializing list of nums
var nums = [];
var K = 6, X = 5;
nums.push(8);
nums.push(13);
nums.push(2);
nums.push(4);
nums.push(7);
// Call the function and
// print the answer
document.write(
    maxSumIncDiv(nums, K, X));
     
// This code is contributed by rutvik_56.
</script>


Output

7

Time Complexity: O(N * log N)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads