Minimum operations to make Array sum at most S from given Array

07 Jan, 2022
Given an array arr[], of size N and an integer S, the task is to find the minimum operations to make the sum of the array less than or equal to S. In each operation:
Any element can be chosen and can be decremented by 1, or
Can be replaced by any other element in the array.
Examples:
Input: arr[]= {1, 2, 1 ,3, 1 ,2, 1}, S= 8Output: 2Explanation: Initially sum of the array is 11.Now decrease 1 at index 0 to 0 and Replace 3 by 0. The sum becomes  7 < 8. So 2 operations.
Input: arr[] = {1,2,3,4}, S= 11Output: 0Explanation: Sum is already < =11 so 0 operations.
Approach: This problem can be solved using the greedy approach and suffix sum by sorting the array. Applying the 1st operation on the minimum element any number of times and then applying the 2nd operation on the suffixes by replacing it with the minimum element after the first operation gives the minimum operations.
First sort the array. Consider performing x operations of 1st type on the arr[0] and then performing the 2nd operation on the suffix of the array of length i. Also consider the sum for this suffix of length i is sufSum.
Sum of the modified array must be <=SSo, the difference to be  subtracted from the sum must be (diff)>= sum – S.
If x operations of type 1 is done on minimum element and type 2 operations are done the suffix of the array from [i,n) the sum of the decreased array is 
cost = x + s – (n-i) * (a[0] – x)cost = (n-i+1)* x-(n-i)* a[0]  +scost >= sum – S = diffs – (n-i) * a[0] + (n-i+1) *x >= diff so x >= (diff – s+(n-i)* a[0]) / (n-i+1)
The minimum value of x is x = ceil((diff -s+ (n-i)* a[0]) / (n-i+1))
So the total operations are x (type-1) + (n-i) type-2 
Follow these steps to solve the above problems:
Initialize a variable sum = 0 and the size of the array to N.
Iterate through the vector and find the sum of the array.
If sum < = S print 0 and return.
Sort the vector and assign diff = sum-S.
Initialize ops = sum-S which is the maximum possible operations.
Initialize s =0 which stores the suffix sum of the vector.
Now traverse from the end of the vector using for loop.
Keep track of suffix sum in s variable.
Initialize a dec variable which is the value to be decremented from the suffix of the arrayIf s-dec is greater than or equal to diff there is no need to decrement arr[0] so assign x =0.Else find the value of x which is the value to be decremented in arr[0] and find the minimum operations.
If s-dec is greater than or equal to diff there is no need to decrement arr[0] so assign x =0.
Else find the value of x which is the value to be decremented in arr[0] and find the minimum operations.
Print the minimum operations
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program for the above approach#include <bits/stdc++.h>using namespace std; // Function to divide and get the ceil valueint ceil_div(int a, int b){    return a / b + ((a ^ b) > 0 && a % b);} // Function to find the minimum costvoid minimum_cost(vector<int> arr, int S){    int sum = 0;    int n = arr.size();         // Find the sum of the array    for (int i = 0; i < arr.size(); i++) {        sum += arr[i];    }         // If sum <= S no operations required    if (sum <= S) {        cout << 0 << endl;        return;    }         // Sort the array    sort(arr.begin(), arr.end());     int diff = sum - S;         // Maximum it requires sum-S operations    // by decrementing    // the arr[0] by 1    int ops = sum - S;    // suffix sum    int s = 0;    int x;     for (int i = n - 1; i > 0; i--) {        s += arr[i];                 // If replacing the last elements        // with doing the first operation        // x = 0 Decrementing the a[i] from        // the suffix [i,n-1]        int dec = (n - i) * arr[0];        if (s - dec >= diff) {            x = 0;        }                 // Find how times the first element        // should be decremented by 1 and        // incremented by 1 which is x        else {            x = max(ceil_div((diff - s + dec),                             (n - i + 1)), 0);        }                 // First operation + second operation        if (x + n - i < ops) {            ops = x + n - i;        }    }     // Print the operations    cout << ops << endl;} // Driver codeint main(){    // Initialize the array    vector<int> arr = { 1, 2, 1, 3, 1, 2, 1 };    int S = 8;         // Function call    minimum_cost(arr, S);     return 0;}
// Java program for the above approach import java.util.Arrays; class GFG {   // Function to divide and get the ceil value  static int ceil_div(int a, int b) {    int temp = 0;    if (((a ^ b) > 0) && ((a % b) > 0)) {      temp = 1;    }    return (a / b) + temp;  }   // Function to find the minimum cost  static void minimum_cost(int[] arr, int S) {    int sum = 0;    int n = arr.length;     // Find the sum of the array    for (int i = 0; i < arr.length; i++) {      sum += arr[i];    }     // If sum <= S no operations required    if (sum <= S) {      System.out.println(0);      return;    }     // Sort the array    Arrays.sort(arr);     int diff = sum - S;     // Maximum it requires sum-S operations    // by decrementing    // the arr[0] by 1    int ops = sum - S;    // suffix sum    int s = 0;    int x;     for (int i = n - 1; i > 0; i--) {      s += arr[i];       // If replacing the last elements      // with doing the first operation      // x = 0 Decrementing the a[i] from      // the suffix [i,n-1]      int dec = (n - i) * arr[0];      if (s - dec >= diff) {        x = 0;      }       // Find how times the first element      // should be decremented by 1 and      // incremented by 1 which is x      else {        x = Math.max(ceil_div((diff - s + dec),                              (n - i + 1)), 0);      }       // First operation + second operation      if (x + n - i < ops) {        ops = x + n - i;      }    }     // Print the operations    System.out.println(ops);  }   // Driver code  public static void main(String args[])  {     // Initialize the array    int[] arr = { 1, 2, 1, 3, 1, 2, 1 };    int S = 8;     // Function call    minimum_cost(arr, S);  }} // This code is contributed by saurabh_jaiswal.
# Python 3 program for the above approach # Function to divide and get the ceil valuedef ceil_div(a,  b):     return a // b + ((a ^ b) > 0 and a % b) # Function to find the minimum costdef minimum_cost(arr, S):     sum = 0    n = len(arr)     # Find the sum of the array    for i in range(len(arr)):        sum += arr[i]     # If sum <= S no operations required    if (sum <= S):        print(0)        return     # Sort the array    arr.sort()     diff = sum - S     # Maximum it requires sum-S operations    # by decrementing    # the arr[0] by 1    ops = sum - S    # suffix sum    s = 0     for i in range(n - 1, -1, -1):        s += arr[i]         # If replacing the last elements        # with doing the first operation        # x = 0 Decrementing the a[i] from        # the suffix [i,n-1]        dec = (n - i) * arr[0]        if (s - dec >= diff):            x = 0         # Find how times the first element        # should be decremented by 1 and        # incremented by 1 which is x        else:            x = max(ceil_div((diff - s + dec),                             (n - i + 1)), 0)         # First operation + second operation        if (x + n - i < ops):            ops = x + n - i     # Print the operations    print(ops) # Driver codeif __name__ == "__main__":     # Initialize the array    arr = [1, 2, 1, 3, 1, 2, 1]    S = 8     # Function call    minimum_cost(arr, S)     # This code is contributed by ukasp.
// C# program for the above approachusing System;class GFG{  // Function to divide and get the ceil value  static int ceil_div(int a, int b) {    int temp = 0;    if (((a ^ b) > 0) && ((a % b) > 0)) {      temp = 1;    }    return (a / b) + temp;  }   // Function to find the minimum cost  static void minimum_cost(int[] arr, int S) {    int sum = 0;    int n = arr.Length;     // Find the sum of the array    for (int i = 0; i < arr.Length; i++) {      sum += arr[i];    }     // If sum <= S no operations required    if (sum <= S) {      Console.WriteLine(0);      return;    }     // Sort the array    Array.Sort(arr);     int diff = sum - S;     // Maximum it requires sum-S operations    // by decrementing    // the arr[0] by 1    int ops = sum - S;    // suffix sum    int s = 0;    int x;     for (int i = n - 1; i > 0; i--) {      s += arr[i];       // If replacing the last elements      // with doing the first operation      // x = 0 Decrementing the a[i] from      // the suffix [i,n-1]      int dec = (n - i) * arr[0];      if (s - dec >= diff) {        x = 0;      }       // Find how times the first element      // should be decremented by 1 and      // incremented by 1 which is x      else {        x = Math.Max(ceil_div((diff - s + dec),                              (n - i + 1)), 0);      }       // First operation + second operation      if (x + n - i < ops) {        ops = x + n - i;      }    }     // Print the operations    Console.Write(ops);  }   // Driver code  public static void Main()  {     // Initialize the array    int[] arr = { 1, 2, 1, 3, 1, 2, 1 };    int S = 8;     // Function call    minimum_cost(arr, S);  }} // This code is contributed by Samim Hossain Mondal.
<script>    // JavaScript program for the above approach     // Function to divide and get the ceil value    const ceil_div = (a, b) => parseInt(a / b) + ((a ^ b) > 0 && a % b);     // Function to find the minimum cost    const minimum_cost = (arr, S) => {        let sum = 0;        let n = arr.length;         // Find the sum of the array        for (let i = 0; i < arr.length; i++) {            sum += arr[i];        }         // If sum <= S no operations required        if (sum <= S) {            document.write("0<br/>");            return;        }         // Sort the array        arr.sort();         let diff = sum - S;         // Maximum it requires sum-S operations        // by decrementing        // the arr[0] by 1        let ops = sum - S;        // suffix sum        let s = 0;        let x;         for (let i = n - 1; i > 0; i--) {            s += arr[i];             // If replacing the last elements            // with doing the first operation            // x = 0 Decrementing the a[i] from            // the suffix [i,n-1]            let dec = (n - i) * arr[0];            if (s - dec >= diff) {                x = 0;            }             // Find how times the first element            // should be decremented by 1 and            // incremented by 1 which is x            else {                x = Math.max(ceil_div((diff - s + dec),                    (n - i + 1)), 0);            }             // First operation + second operation            if (x + n - i < ops) {                ops = x + n - i;            }        }         // Print the operations        document.write(`${ops}<br/>`);    }     // Driver code     // Initialize the array    let arr = [1, 2, 1, 3, 1, 2, 1];    let S = 8;     // Function call    minimum_cost(arr, S); // This code is contributed by rakeshsahni </script>
  
2
Time Complexity: O(N* logN)Space Complexity: O(1)
rakeshsahni
_saurabh_jaiswal
samim2000
ukasp
Algo-Geek 2021
suffix-sum
Algo Geek
Arrays
Greedy
Mathematical
Arrays
Greedy
Mathematical
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Count of ordered pairs (i, j) such that arr[i] and arr[j] concatenates to X
Number of ways to divide a N elements equally into group of at least 2
Sort strings on the basis of their numeric part
Print all valid words from given dictionary that are possible using Characters of given Array
Check if the given string is valid English word or not
Arrays in Java
Write a program to reverse an array or string
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Largest Sum Contiguous Subarray