Given an array A[] consisting of N non-negative integers, and an integer K, the task is to find the number of ways ‘+’ and ‘-‘ operators can be placed in front of elements of the array A[] such that the sum of the array becomes K.
Examples:
Input: A[] = {1, 1, 2, 3}, N = 4, K = 1
Output: 3
Explanation: Three possible ways are:
- + 1 + 1 + 2 – 3 = 1
- + 1 – 1 – 2 + 3 = 1
- – 1 + 1 – 1 + 3 = 1
Input: A[] = {1, 1, 1, 1, 1}, N = 5, K = 3
Output: 6
Approach: The problem can be solved based on the following observations:
- Store the sum of elements having ‘+’ in front of that element and ‘-‘ in front of that element in variables, say P1 and P2, such that the sum of the array becomes K.
- Store the total sum of the array A[] in a variable, say K.
- Therefore, following equations arises:
- P1 + P2 = sum
- P1 – P2 = K
- Solving the above equations obtains P1 = (sum + K) / 2.
- Therefore, the problem has transformed into finding the number of subsets with sum P1.
- If an element of A is equal to 0, both ‘+’ and ‘-‘ operators work in valid arrangements, thus, the 0s can be safely ignored and separately calculated.
Hence, the problem can be solved using Dynamic Programming. Follow the steps below to solve the problem:
- Calculate and store the sum of elements of the array A[] and the number of 0s in A[] in variables sum and c respectively.
- If K is greater than sum or (sum + K) is odd, return 0.
- Add K to sum and divide it by 2, i.e. sum = (sum + K) / 2, which is the required sum. Find the number of subsets equal to that sum.
- Create a 2D dp array of dimensions N*sum. where dp[i][j] represents the number of subsets up to i-1 that have sum j.
- The base cases required to be considered are as follows:
- dp[0][i] = 0, for 0 <= i <= sum, as no elements from the array A[] has been considered
- dp[i][0] = 1, for 0 <= i <= N, as obtaining a sum 0 is always possible.
- Iterate from 1 to N, and for each current index i, perform the following operations:
- Iterate from 1 to sum and for each current index j, perform the following transitions:
- If A[i – 1] is less than j and A[i – 1] is not equal to 0, set dp[i][j] = dp[i – 1][j] + dp[i – 1][j – A[i – 1]].
- Otherwise, copy the previous state, i.e. dp[i][j] = dp[i – 1][j].
- Finally, return the product of dp[N][sum] and 2c (to account for the 0s) i.e dp[N][sum]*2c.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int solve( int A[], int N, int K)
{
int sum = 0;
int c = 0;
for ( int i = 0; i < N; i++) {
sum += A[i];
if (A[i] == 0)
c++;
}
if (K > sum || (sum + K) % 2)
return 0;
sum = (sum + K) / 2;
int dp[N + 1][sum + 1];
for ( int i = 0; i <= sum; i++)
dp[0][i] = 0;
for ( int i = 0; i <= N; i++)
dp[i][0] = 1;
for ( int i = 1; i <= N; i++) {
for ( int j = 1; j <= sum; j++) {
if (A[i - 1] <= j && A[i - 1])
dp[i][j] = dp[i - 1][j]
+ dp[i - 1][j - A[i - 1]];
else
dp[i][j] = dp[i - 1][j];
}
}
return dp[N][sum] + pow (2, c);
}
int main()
{
int A[] = { 1, 1, 2, 3 };
int N = sizeof (A) / sizeof (A[0]);
int K = 3;
cout << solve(A, N, K) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG{
static int solve( int A[], int N, int K)
{
int sum = 0 ;
int c = 0 ;
for ( int i = 0 ; i < N; i++) {
sum += A[i];
if (A[i] == 0 )
c++;
}
if ((K > sum) || (((sum + K) % 2 ) != 0 ))
return 0 ;
sum = (sum + K) / 2 ;
int dp[][] = new int [N + 1 ][sum + 1 ];
for ( int i = 0 ; i <= sum; i++)
dp[ 0 ][i] = 0 ;
for ( int i = 0 ; i <= N; i++)
dp[i][ 0 ] = 1 ;
for ( int i = 1 ; i <= N; i++) {
for ( int j = 1 ; j <= sum; j++) {
if ((A[i - 1 ] <= j) && (A[i - 1 ] != 0 ))
dp[i][j] = dp[i - 1 ][j]
+ dp[i - 1 ][j - A[i - 1 ]];
else
dp[i][j] = dp[i - 1 ][j];
}
}
return dp[N][sum] + ( int )Math.pow( 2 , c);
}
public static void main(String[] args)
{
int A[] = { 1 , 1 , 2 , 3 };
int N = A.length;
int K = 3 ;
System.out.print(solve(A, N, K));
}
}
|
Python3
def solve(A, N, K):
sum = 0
c = 0
for i in range (N):
sum + = A[i]
if (A[i] = = 0 ):
c + = 1
if (K > sum or ( sum + K) % 2 ):
return 0
sum = ( sum + K) / / 2
dp = [[ 0 for i in range ( sum + 1 )]
for j in range (N + 1 )]
for i in range ( sum + 1 ):
dp[ 0 ][i] = 0
for i in range (N + 1 ):
dp[i][ 0 ] = 1
for i in range ( 1 , N + 1 , 1 ):
for j in range ( 1 , sum + 1 , 1 ):
if (A[i - 1 ] < = j and A[i - 1 ]):
dp[i][j] = (dp[i - 1 ][j] +
dp[i - 1 ][j - A[i - 1 ]])
else :
dp[i][j] = dp[i - 1 ][j]
return dp[N][ sum ] + pow ( 2 , c)
if __name__ = = '__main__' :
A = [ 1 , 1 , 2 , 3 ]
N = len (A)
K = 3
print (solve(A, N, K))
|
C#
using System;
public class GFG
{
static int solve( int [] A, int N, int K)
{
int sum = 0;
int c = 0;
for ( int i = 0; i < N; i++) {
sum += A[i];
if (A[i] == 0)
c++;
}
if ((K > sum) || (((sum + K) % 2) != 0))
return 0;
sum = (sum + K) / 2;
int [, ] dp= new int [N + 1, sum + 1];
for ( int i = 0; i <= sum; i++)
dp[0, i] = 0;
for ( int i = 0; i <= N; i++)
dp[i,0] = 1;
for ( int i = 1; i <= N; i++) {
for ( int j = 1; j <= sum; j++) {
if ((A[i - 1] <= j) && (A[i - 1] != 0))
dp[i,j] = dp[i - 1,j]
+ dp[i - 1,j - A[i - 1]];
else
dp[i,j] = dp[i - 1,j];
}
}
return dp[N, sum] + ( int )Math.Pow(2, c);
}
static public void Main ()
{
int [] A = { 1, 1, 2, 3 };
int N = A.Length;
int K = 3;
Console.Write(solve(A, N, K));
}
}
|
Javascript
<script>
function solve(A, N, K)
{
let sum = 0;
let c = 0;
for (let i = 0; i < N; i++) {
sum += A[i];
if (A[i] == 0)
c++;
}
if (K > sum || (sum + K) % 2)
return 0;
sum = (sum + K) / 2;
let dp = new Array(N + 1);
for ( var i = 0; i < dp.length; i++) {
dp[i] = new Array(sum + 1);
}
for (let i = 0; i <= sum; i++)
dp[0][i] = 0;
for (let i = 0; i <= N; i++)
dp[i][0] = 1;
for (let i = 1; i <= N; i++) {
for (let j = 1; j <= sum; j++) {
if (A[i - 1] <= j && A[i - 1])
dp[i][j] = dp[i - 1][j]
+ dp[i - 1][j - A[i - 1]];
else
dp[i][j] = dp[i - 1][j];
}
}
return dp[N][sum] + Math.pow(2, c);
}
let A = [1, 1, 2, 3];
let N = A.length;
let K = 3;
document.write(solve(A, N, K));
</script>
|
Time Complexity: O(N * sum) where N is the size of the array A and sum is the target sum. This is because we are filling a 2D DP array of size (N+1) x (sum+1) with nested loops.
Auxiliary Space: O(N * sum)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
10 Apr, 2023
Like Article
Save Article