Minimize count of flips required to make sum of the given array equal to 0

• Last Updated : 28 Mar, 2023

Given an array arr[] consisting of N integers, the task is to minimize the count of elements required to be multiplied by -1 such that the sum of array elements is 0. If it is not possible to make the sum 0, print “-1”.

Examples:

Input: arr[] = {2, 3, 1, 4}
Output: 2
Explanation:
Multiply arr[0] by -1. Therefore, the array modifies to {-2, 3, 1, 4}.
Multiply arr[1] by -1. Therefore, the array modifies to {-2, -3, 1, 4}
Therefore, the sum of the modified array is 0 and the minimum operations required is 2.

Input: arr[] = {2}
Output: -1.

Naive Approach: The simplest approach is to divide the array into two subsets in every possible way. For each division, check if the difference of their subset-sum is 0 or not. If found to be 0, then the length of the smaller subset is the result.
Time Complexity: O(2N)
Auxiliary Space: O(N)

Efficient Approach: To optimize the above approach, the idea is to use Dynamic Programming. Follow the steps to solve the problem:

• To make the sum of all array elements equal to 0, divide the given array elements into two subsets having an equal sum.
• Out of all the subsets possible of the given array, the subset whose size is the minimum of all is chosen.
• If the sum of the given array is odd, no subset is possible to make the sum 0, hence return -1
• Else, try all possible subset sums of the array and check if the sum of the subset is equal to sum/2. where the sum is the sum of all elements of the array.
• The recurrence relation of dp[] is:

dp(i, j) = min (dp(i+1, j – arr[i]]+1), dp(i+1, j))
where

dp (i, j) represents the minimum operations to make sum j equal to 0 using elements having index [i, N-1].
j represents the current sum.
i represents the current index.

• Using the above recurrence, print dp(0, sum/2) as the result.

Below is the implementation of the above approach:

C++

 `// C++ program for the above approach` `#include ``using` `namespace` `std;` `// Initialize dp[][]``int` `dp[2001][2001];` `// Function to find the minimum number``// of operations to make sum of A[] 0``int` `solve(vector<``int``>& A, ``int` `i,``          ``int` `sum, ``int` `N)``{``    ``// Initialize answer``    ``int` `res = 2001;` `    ``// Base case``    ``if` `(sum < 0 or (i == N and sum != 0)) {``        ``return` `2001;``    ``}` `    ``// Otherwise, return 0``    ``if` `(sum == 0 or i >= N) {``        ``return` `dp[i][sum] = 0;``    ``}` `    ``// Pre-computed subproblem``    ``if` `(dp[i][sum] != -1) {``        ``return` `dp[i][sum];``    ``}` `    ``// Recurrence relation for finding``    ``// the minimum of the sum of subsets``    ``res = min(solve(A, i + 1, sum - A[i], N) + 1,``              ``solve(A, i + 1, sum, N));` `    ``// Return the result``    ``return` `dp[i][sum] = res;``}` `// Function to find the minimum number``// of elements required to be flipped``// to make sum the array equal to 0``void` `minOp(vector<``int``>& A, ``int` `N)``{``    ``int` `sum = 0;` `    ``// Find the sum of array``    ``for` `(``auto` `it : A) {``        ``sum += it;``    ``}` `    ``if` `(sum % 2 == 0) {` `        ``// Initialise dp[][]  with -1``        ``memset``(dp, -1, ``sizeof``(dp));` `        ``int` `ans = solve(A, 0, sum / 2, N);` `        ``// No solution exists``        ``if` `(ans < 0 || ans > N) {``            ``cout << ``"-1"` `<< endl;``        ``}` `        ``// Otherwise``        ``else` `{``            ``cout << ans << endl;``        ``}``    ``}` `    ``// If sum is odd, no``    ``// subset is possible``    ``else` `{``        ``cout << ``"-1"` `<< endl;``    ``}``}` `// Driver Code``int` `main()``{``    ``vector<``int``> A = { 2, 3, 1, 4 };``    ``int` `N = A.size();` `    ``// Function Call``    ``minOp(A, N);` `    ``return` `0;``}`

Java

 `// Java program for the above approach``class` `GFG``{` `// Initialize dp[][]``static` `int` `[][]dp = ``new` `int``[``2001``][``2001``];` `// Function to find the minimum number``// of operations to make sum of A[] 0``static` `int` `solve(``int` `[]A, ``int` `i,``          ``int` `sum, ``int` `N)``{``  ` `    ``// Initialize answer``    ``int` `res = ``2001``;` `    ``// Base case``    ``if` `(sum < ``0` `|| (i == N && sum != ``0``))``    ``{``        ``return` `2001``;``    ``}` `    ``// Otherwise, return 0``    ``if` `(sum == ``0` `|| i >= N)``    ``{``        ``return` `dp[i][sum] = ``0``;``    ``}` `    ``// Pre-computed subproblem``    ``if` `(dp[i][sum] != -``1``)``    ``{``        ``return` `dp[i][sum];``    ``}` `    ``// Recurrence relation for finding``    ``// the minimum of the sum of subsets``    ``res = Math.min(solve(A, i + ``1``, sum - A[i], N) + ``1``,``              ``solve(A, i + ``1``, sum, N));` `    ``// Return the result``    ``return` `dp[i][sum] = res;``}` `// Function to find the minimum number``// of elements required to be flipped``// to make sum the array equal to 0``static` `void` `minOp(``int` `[]A, ``int` `N)``{``    ``int` `sum = ``0``;` `    ``// Find the sum of array``    ``for` `(``int` `it : A)``    ``{``        ``sum += it;``    ``}` `    ``if` `(sum % ``2` `== ``0``)``    ``{` `        ``// Initialise dp[][]  with -1``        ``for``(``int` `i = ``0``; i < ``2001``; i++)``        ``{``            ``for` `(``int` `j = ``0``; j < ``2001``; j++)``            ``{``                ``dp[i][j] = -``1``;``            ``}``        ``}` `        ``int` `ans = solve(A, ``0``, sum / ``2``, N);` `        ``// No solution exists``        ``if` `(ans < ``0` `|| ans > N)``        ``{``            ``System.out.print(``"-1"` `+``"\n"``);``        ``}` `        ``// Otherwise``        ``else``        ``{``            ``System.out.print(ans +``"\n"``);``        ``}``    ``}` `    ``// If sum is odd, no``    ``// subset is possible``    ``else``    ``{``        ``System.out.print(``"-1"` `+``"\n"``);``    ``}``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``    ``int` `[]A = { ``2``, ``3``, ``1``, ``4` `};``    ``int` `N = A.length;` `    ``// Function Call``    ``minOp(A, N);``}``}` `// This code is contributed by 29AjayKumar`

Python3

 `# Python program for the above approach` `# Initialize dp[][]``dp ``=` `[[``-``1` `for` `i ``in` `range``(``2001``)] ``for` `j ``in` `range``(``2001``)]` `# Function to find the minimum number``# of operations to make sum of A[] 0``def` `solve(A, i, ``sum``, N):``  ` `    ``# Initialize answer``    ``res ``=` `2001` `    ``# Base case``    ``if` `(``sum` `< ``0` `or` `(i ``=``=` `N ``and` `sum` `!``=` `0``)):``        ``return` `2001` `    ``# Otherwise, return 0``    ``if` `(``sum` `=``=` `0` `or` `i >``=` `N):``        ``dp[i][``sum``] ``=` `0``        ``return` `0` `    ``# Pre-computed subproblem``    ``if` `(dp[i][``sum``] !``=` `-``1``):``        ``return` `dp[i][``sum``]` `    ``# Recurrence relation for finding``    ``# the minimum of the sum of subsets``    ``res ``=` `min``(solve(A, i ``+` `1``, ``sum` `-` `A[i], N) ``+` `1``,``              ``solve(A, i ``+` `1``, ``sum``, N))` `    ``# Return the result``    ``dp[i][``sum``] ``=` `res``    ``return` `res` `# Function to find the minimum number``# of elements required to be flipped``# to make sum the array equal to 0``def` `minOp(A, N):``    ``sum` `=` `0` `    ``# Find the sum of array``    ``for` `it ``in` `A:``        ``sum` `+``=` `it   ``    ``if` `(``sum` `%` `2` `=``=` `0``):``      ` `        ``# Initialise dp[][]  with -1``        ``dp ``=` `[[``-``1` `for` `i ``in` `range``(``2001``)] ``for` `j ``in` `range``(``2001``)]``        ``ans ``=` `solve(A, ``0``, ``sum` `/``/` `2``, N)` `        ``# No solution exists``        ``if` `(ans < ``0` `or` `ans > N):``            ``print``(``"-1"``)``        ` `        ``# Otherwise``        ``else``:``            ``print``(ans)` `    ``# If sum is odd, no``    ``# subset is possible``    ``else``:``        ``print``(``-``1``)` `# Driver Code``A ``=` `[ ``2``, ``3``, ``1``, ``4` `]``N ``=` `len``(A)` `# Function Call``minOp(A, N)` `# This code is contributed by rohitsingh07052.`

C#

 `// C# program for the above approach``using` `System;``using` `System.Collections.Generic;``public` `class` `GFG``{` `// Initialize [,]dp``static` `int` `[,]dp = ``new` `int``[2001,2001];` `// Function to find the minimum number``// of operations to make sum of []A 0``static` `int` `solve(``int` `[]A, ``int` `i,``          ``int` `sum, ``int` `N)``{``  ` `    ``// Initialize answer``    ``int` `res = 2001;` `    ``// Base case``    ``if` `(sum < 0 || (i == N && sum != 0))``    ``{``        ``return` `2001;``    ``}` `    ``// Otherwise, return 0``    ``if` `(sum == 0 || i >= N)``    ``{``        ``return` `dp[i, sum] = 0;``    ``}` `    ``// Pre-computed subproblem``    ``if` `(dp[i, sum] != -1)``    ``{``        ``return` `dp[i, sum];``    ``}` `    ``// Recurrence relation for finding``    ``// the minimum of the sum of subsets``    ``res = Math.Min(solve(A, i + 1, sum - A[i], N) + 1,``              ``solve(A, i + 1, sum, N));` `    ``// Return the result``    ``return` `dp[i, sum] = res;``}` `// Function to find the minimum number``// of elements required to be flipped``// to make sum the array equal to 0``static` `void` `minOp(``int` `[]A, ``int` `N)``{``    ``int` `sum = 0;` `    ``// Find the sum of array``    ``foreach` `(``int` `it ``in` `A)``    ``{``        ``sum += it;``    ``}` `    ``if` `(sum % 2 == 0)``    ``{` `        ``// Initialise [,]dp  with -1``        ``for``(``int` `i = 0; i < 2001; i++)``        ``{``            ``for` `(``int` `j = 0; j < 2001; j++)``            ``{``                ``dp[i, j] = -1;``            ``}``        ``}` `        ``int` `ans = solve(A, 0, sum / 2, N);` `        ``// No solution exists``        ``if` `(ans < 0 || ans > N)``        ``{``            ``Console.Write(``"-1"` `+``"\n"``);``        ``}` `        ``// Otherwise``        ``else``        ``{``            ``Console.Write(ans +``"\n"``);``        ``}``    ``}` `    ``// If sum is odd, no``    ``// subset is possible``    ``else``    ``{``        ``Console.Write(``"-1"` `+``"\n"``);``    ``}``}` `// Driver Code``public` `static` `void` `Main(String[] args)``{``    ``int` `[]A = { 2, 3, 1, 4 };``    ``int` `N = A.Length;` `    ``// Function Call``    ``minOp(A, N);``}``}` `// This code is contributed by 29AjayKumar`

Javascript

 ``

Output:

`2`

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

My Personal Notes arrow_drop_up