Open In App

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

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:

Examples:



Input: arr[]= {1, 2, 1 ,3, 1 ,2, 1}, S= 8
Output: 2
Explanation: 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= 11
Output: 0
Explanation: 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 <=S
So, 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]  +s
cost >= sum – S = diff
s – (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:

Below is the implementation of the above approach:




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to divide and get the ceil value
int ceil_div(int a, int b)
{
    return a / b + ((a ^ b) > 0 && a % b);
}
 
// Function to find the minimum cost
void 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 code
int 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 value
def ceil_div(a,  b):
 
    return a // b + ((a ^ b) > 0 and a % b)
 
# Function to find the minimum cost
def 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 code
if __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 approach
using 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>

 
 

Output
2

Time Complexity: O(N* logN)
Space Complexity: O(1)


Article Tags :