 GFG App
Open App Browser
Continue

# Count of subsets with sum equal to X | Set-2

Given an array arr[] of length N and an integer X, the task is to find the number of subsets with a sum equal to X.

Examples:

Input: arr[] = {1, 2, 3, 3}, X = 6
Output:
Explanation: All the possible subsets are {1, 2, 3}, {1, 2, 3} and {3, 3}.

Input: arr[] = {1, 1, 1, 1}, X = 1
Output:

Space Efficient Approach: This problem has already been discussed in the article here. This article focuses on a similar Dynamic Programming approach which uses only O(X) space. The standard DP relation of solving this problem as discussed in the above article is:

dp[i][C] = dp[i – 1][C – arr[i]] + dp[i – 1][C]

where dp[i][C] stores the number of subsets of the subarray arr[0… i] such that their sum is equal to C. It can be noted that the dp[i]th state only requires the array values of the dp[i – 1]th state. Hence the above relation can be simplified into the following:

dp[C] = dp[C – arr[i]] + dp[C]

Here, a good point to note is that during the calculation of dp[C], the variable C must be iterated in decreasing order in order to avoid the duplicity of arr[i] in the subset-sum count.

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the above approach` `#include ` `using` `namespace` `std;`   `// Function to find the count of subsets` `// having the given sum` `int` `subsetSum(``int` `arr[], ``int` `n, ``int` `sum)` `{` `    ``// Initializing the dp-table` `    ``int` `dp[sum + 1] = {};`   `    ``// Case for sum of elements in empty set` `    ``dp = 1;`   `    ``// Loop to iterate over array elements` `    ``for` `(``int` `i = 0; i < n; i++) {` `        ``for` `(``int` `j = sum; j >= 0; j--) {`   `            ``// If j-arr[i] is a valid index` `            ``if` `(j - arr[i] >= 0) {` `                ``dp[j] = dp[j - arr[i]] + dp[j];` `            ``}` `        ``}` `    ``}`   `    ``// Return answer` `    ``return` `dp[sum];` `}`   `// Driven Code` `int` `main()` `{` `    ``int` `arr[] = { 1, 1, 1, 1 };` `    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);` `    ``int` `sum = 1;`   `    ``cout << subsetSum(arr, N, sum) << endl;`   `    ``return` `0;` `}`

## Java

 `// Java implementation of the above approach` `import` `java.util.*;` `public` `class` `GFG` `{` `  `  `// Function to find the count of subsets` `// having the given sum` `static` `int` `subsetSum(``int` `arr[], ``int` `n, ``int` `sum)` `{` `    ``// Initializing the dp-table` `    ``int` `dp[] = ``new` `int``[sum + ``1``];`   `    ``// Case for sum of elements in empty set` `    ``dp[``0``] = ``1``;`   `    ``// Loop to iterate over array elements` `    ``for` `(``int` `i = ``0``; i < n; i++) {` `        ``for` `(``int` `j = sum; j >= ``0``; j--) {`   `            ``// If j-arr[i] is a valid index` `            ``if` `(j - arr[i] >= ``0``) {` `                ``dp[j] = dp[j - arr[i]] + dp[j];` `            ``}` `        ``}` `    ``}`   `    ``// Return answer` `    ``return` `dp[sum];` `}`   `// Driver code` `public` `static` `void` `main(String args[])` `{` `    ``int` `arr[] = { ``1``, ``1``, ``1``, ``1` `};` `    ``int` `N = arr.length;` `    ``int` `sum = ``1``;` `    `  `    ``System.out.println(subsetSum(arr, N, sum));` `}` `}`   `// This code is contributed by Samim Hossain Mondal.`

## Python3

 `# Python implementation of the above approach`   `# Function to find the count of subsets` `# having the given sum` `def` `subsetSum(arr, n, ``sum``):`   `    ``# Initializing the dp-table` `    ``dp ``=` `[``0``] ``*` `(``sum` `+` `1``)`   `    ``# Case for sum of elements in empty set` `    ``dp[``0``] ``=` `1``;`   `    ``# Loop to iterate over array elements` `    ``for` `i ``in` `range``(n):` `        ``for` `j ``in` `range``(``sum``, ``0``, ``-``1``):`   `            ``# If j-arr[i] is a valid index` `            ``if` `(j ``-` `arr[i] >``=` `0``):` `                ``dp[j] ``=` `dp[j ``-` `arr[i]] ``+` `dp[j];` `    ``# Return answer` `    ``return` `dp[``sum``];`   `# Driven Code` `arr ``=` `[``1``, ``1``, ``1``, ``1``];` `N ``=` `len``(arr)` `sum` `=` `1``;`   `print``(subsetSum(arr, N, ``sum``))`   `# This code is contributed by gfgking.`

## C#

 `// C# implementation of the above approach` `using` `System;`   `public` `class` `GFG` `{` `  `  `// Function to find the count of subsets` `// having the given sum` `static` `int` `subsetSum(``int` `[]arr, ``int` `n, ``int` `sum)` `{` `  `  `    ``// Initializing the dp-table` `    ``int` `[]dp = ``new` `int``[sum + 1];`   `    ``// Case for sum of elements in empty set` `    ``dp = 1;`   `    ``// Loop to iterate over array elements` `    ``for` `(``int` `i = 0; i < n; i++) {` `        ``for` `(``int` `j = sum; j >= 0; j--) {`   `            ``// If j-arr[i] is a valid index` `            ``if` `(j - arr[i] >= 0) {` `                ``dp[j] = dp[j - arr[i]] + dp[j];` `            ``}` `        ``}` `    ``}`   `    ``// Return answer` `    ``return` `dp[sum];` `}`   `// Driver code` `public` `static` `void` `Main(String []args)` `{` `    ``int` `[]arr = { 1, 1, 1, 1 };` `    ``int` `N = arr.Length;` `    ``int` `sum = 1;` `    `  `    ``Console.WriteLine(subsetSum(arr, N, sum));` `}` `}`   `// This code is contributed by shikhasingrajput`

## Javascript

 ``

Output

`4`

Time Complexity: O(N * X)
Auxiliary Space: O(X)

Another Approach (Memoised dynamic programming):

The problem can be solved using memoised dynamic programming. We can create a 2D dp array where dp[i][j] represents the number of subsets of arr[0…i] with sum equal to j. The recursive relation for dp[i][j] can be defined as follows:

•    If i = 0, dp[j] = 1 if arr == j else 0
•    If i > 0, dp[i][j] = dp[i-1][j] + dp[i-1][j-arr[i]], if j >= arr[i]
•    If i > 0, dp[i][j] = dp[i-1][j], if j < arr[i]

The base case for i = 0 can be easily computed as the subset containing only the first element of the array has a sum equal to arr and no other sum. For all other i > 0, we need to consider two cases: either the ith element is included in a subset with sum j, or it is not included. If it is not included, we need to find the number of subsets of arr[0…(i-1)] with sum equal to j. If it is included, we need to find the number of subsets of arr[0…(i-1)] with sum equal to (j – arr[i]).

The final answer will be stored in dp[N-1][X], as we need to find the number of subsets of arr[0…N-1] with sum equal to X.

Algorithm:

1.     Define a recursive function countSubsets(arr, X, dp, i, sum) that takes the following parameters:

• arr: The input array
• X: The target sum
• dp: The memoization table
• i: The index of the current element being considered
• sum: The current sum of elements in the subset
2.    If i is less than 0, return 1 if sum is equal to X, otherwise return 0
3.    If dp[i][sum] is not equal to -1, return dp[i][sum]
4.    Initialize ans to countSubsets(arr, X, dp, i – 1, sum)
5.    If sum plus the ith element of arr is less than or equal to X, add countSubsets(arr, X, dp, i – 1, sum + arr[i]) to ans
6.    Set dp[i][sum] to ans
7.    Return ans
8.    Initialize the DP table dp to all -1 values
9.    Call countSubsets(arr, X, dp, arr.size() – 1, 0) and store the result in ans
10.    Print ans as the number of subsets with a sum equal to X in arr

Below is the implementation of the approach:

## C++

 `#include ` `using` `namespace` `std;`   `// Recursive function to count subsets with a sum equal to X` `int` `countSubsets(vector<``int``>& arr, ``int` `X, vector> &dp, ``int` `i, ``int` `sum) {` `    ``// Base case: if we have reached the end of the array` `    ``if` `(i < 0) {` `        ``// If the sum is equal to X, return 1, else return 0` `        ``return` `(sum == X ? 1 : 0);` `    ``}`   `    ``// If the subproblem has already been solved, return the solution` `    ``if` `(dp[i][sum] != -1) {` `        ``return` `dp[i][sum];` `    ``}`   `    ``// If we don't include the current element in the subset` `    ``int` `ans = countSubsets(arr, X, dp, i - 1, sum);`   `    ``// If we include the current element in the subset` `    ``if` `(sum + arr[i] <= X) {` `        ``ans += countSubsets(arr, X, dp, i - 1, sum + arr[i]);` `    ``}`   `    ``// Memoize the solution to the subproblem` `    ``dp[i][sum] = ans;`   `    ``// Return the solution to the current subproblem` `    ``return` `ans;` `}`   `int` `main() {` `    ``// Example usage` `    ``vector<``int``> arr = { 1, 1, 1, 1 };` `    ``int` `X = 1;` `    `  `    ``// Initialize the DP table with -1` `      ``vector> dp(arr.size()+1, vector<``int``>(X+1, -1));`   `    ``// Count the number of subsets with a sum equal to X` `    ``int` `ans = countSubsets(arr, X, dp, arr.size() - 1, 0);`   `    ``// Print the result` `    ``cout << ans << endl;`   `    ``return` `0;` `}`

Output

`4`

Time Complexity: O(N * X), where N is the size of the array and X is the target sum. This is because each subproblem is solved only once, and there are N * X possible subproblems.

Auxiliary Space: O(N * X), as we are using a 2D array of size (N + 1) * (X + 1) to store the solutions to the subproblems.

My Personal Notes arrow_drop_up