Minimum operations to make Array sum at most S from given Array
Last Updated :
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= 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:
- 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 array
- 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++
#include <bits/stdc++.h>
using namespace std;
int ceil_div( int a, int b)
{
return a / b + ((a ^ b) > 0 && a % b);
}
void minimum_cost(vector< int > arr, int S)
{
int sum = 0;
int n = arr.size();
for ( int i = 0; i < arr.size(); i++) {
sum += arr[i];
}
if (sum <= S) {
cout << 0 << endl;
return ;
}
sort(arr.begin(), arr.end());
int diff = sum - S;
int ops = sum - S;
int s = 0;
int x;
for ( int i = n - 1; i > 0; i--) {
s += arr[i];
int dec = (n - i) * arr[0];
if (s - dec >= diff) {
x = 0;
}
else {
x = max(ceil_div((diff - s + dec),
(n - i + 1)), 0);
}
if (x + n - i < ops) {
ops = x + n - i;
}
}
cout << ops << endl;
}
int main()
{
vector< int > arr = { 1, 2, 1, 3, 1, 2, 1 };
int S = 8;
minimum_cost(arr, S);
return 0;
}
|
Java
import java.util.Arrays;
class GFG {
static int ceil_div( int a, int b) {
int temp = 0 ;
if (((a ^ b) > 0 ) && ((a % b) > 0 )) {
temp = 1 ;
}
return (a / b) + temp;
}
static void minimum_cost( int [] arr, int S) {
int sum = 0 ;
int n = arr.length;
for ( int i = 0 ; i < arr.length; i++) {
sum += arr[i];
}
if (sum <= S) {
System.out.println( 0 );
return ;
}
Arrays.sort(arr);
int diff = sum - S;
int ops = sum - S;
int s = 0 ;
int x;
for ( int i = n - 1 ; i > 0 ; i--) {
s += arr[i];
int dec = (n - i) * arr[ 0 ];
if (s - dec >= diff) {
x = 0 ;
}
else {
x = Math.max(ceil_div((diff - s + dec),
(n - i + 1 )), 0 );
}
if (x + n - i < ops) {
ops = x + n - i;
}
}
System.out.println(ops);
}
public static void main(String args[])
{
int [] arr = { 1 , 2 , 1 , 3 , 1 , 2 , 1 };
int S = 8 ;
minimum_cost(arr, S);
}
}
|
Python3
def ceil_div(a, b):
return a / / b + ((a ^ b) > 0 and a % b)
def minimum_cost(arr, S):
sum = 0
n = len (arr)
for i in range ( len (arr)):
sum + = arr[i]
if ( sum < = S):
print ( 0 )
return
arr.sort()
diff = sum - S
ops = sum - S
s = 0
for i in range (n - 1 , - 1 , - 1 ):
s + = arr[i]
dec = (n - i) * arr[ 0 ]
if (s - dec > = diff):
x = 0
else :
x = max (ceil_div((diff - s + dec),
(n - i + 1 )), 0 )
if (x + n - i < ops):
ops = x + n - i
print (ops)
if __name__ = = "__main__" :
arr = [ 1 , 2 , 1 , 3 , 1 , 2 , 1 ]
S = 8
minimum_cost(arr, S)
|
C#
using System;
class GFG
{
static int ceil_div( int a, int b) {
int temp = 0;
if (((a ^ b) > 0) && ((a % b) > 0)) {
temp = 1;
}
return (a / b) + temp;
}
static void minimum_cost( int [] arr, int S) {
int sum = 0;
int n = arr.Length;
for ( int i = 0; i < arr.Length; i++) {
sum += arr[i];
}
if (sum <= S) {
Console.WriteLine(0);
return ;
}
Array.Sort(arr);
int diff = sum - S;
int ops = sum - S;
int s = 0;
int x;
for ( int i = n - 1; i > 0; i--) {
s += arr[i];
int dec = (n - i) * arr[0];
if (s - dec >= diff) {
x = 0;
}
else {
x = Math.Max(ceil_div((diff - s + dec),
(n - i + 1)), 0);
}
if (x + n - i < ops) {
ops = x + n - i;
}
}
Console.Write(ops);
}
public static void Main()
{
int [] arr = { 1, 2, 1, 3, 1, 2, 1 };
int S = 8;
minimum_cost(arr, S);
}
}
|
Javascript
<script>
const ceil_div = (a, b) => parseInt(a / b) + ((a ^ b) > 0 && a % b);
const minimum_cost = (arr, S) => {
let sum = 0;
let n = arr.length;
for (let i = 0; i < arr.length; i++) {
sum += arr[i];
}
if (sum <= S) {
document.write( "0<br/>" );
return ;
}
arr.sort();
let diff = sum - S;
let ops = sum - S;
let s = 0;
let x;
for (let i = n - 1; i > 0; i--) {
s += arr[i];
let dec = (n - i) * arr[0];
if (s - dec >= diff) {
x = 0;
}
else {
x = Math.max(ceil_div((diff - s + dec),
(n - i + 1)), 0);
}
if (x + n - i < ops) {
ops = x + n - i;
}
}
document.write(`${ops}<br/>`);
}
let arr = [1, 2, 1, 3, 1, 2, 1];
let S = 8;
minimum_cost(arr, S);
</script>
|
Time Complexity: O(N* logN)
Space Complexity: O(1)
Share your thoughts in the comments
Please Login to comment...