Given an integer array arr[] of size N and an integer X, the task is to count the number of subsequences in that array such that its sum is less than or equal to X.
Note: 1 <= N <= 1000 and 1 <= X <= 1000, where N is the size of the array.
Examples:
Input : arr[] = {84, 87, 73}, X = 100
Output : 3
Explanation: The three subsequences with sum less than or equal to 100 are {84}, {87} and {73}.Input : arr[] = {25, 13, 40}, X = 50
Output : 4
Explanation: The four subsequences with sum less than or equal to 50 are {25}, {13}, {40} and {25, 13}.
Naive Approach: Generate all the subsequences of the array and check if the sum is less than or equal to X.
Time complexity:O(2N)
Efficient Approach: Generate the count of subsequences using Dynamic Programming. In order to solve the problem, follow the steps below:
- For any index ind, if arr[ind] ? X then, the count of subsequences including as well as excluding the element at the current index:
countSubsequence(ind, X) = countSubsequence(ind + 1, X) (excluding) + countSubsequence(ind + 1, X – arr[ind]) (including)
- Else, count subsequences excluding the current index:
countSubsequence(ind, X) = countSubsequence(ind + 1, X) (excluding)
- Finally, subtract 1 from the final count returned by the function as it also counts an empty subsequence.
Below is the implementation of the above approach:
// C++ Program to count number // of subsequences in an array // with sum less than or equal to X #include <bits/stdc++.h> using namespace std;
// Utility function to return the count // of subsequence in an array with sum // less than or equal to X int countSubsequenceUtil(
int ind, int sum,
int * A, int N,
vector<vector< int > >& dp)
{ // Base condition
if (ind == N)
return 1;
// Return if the sub-problem
// is already calculated
if (dp[ind][sum] != -1)
return dp[ind][sum];
// Check if the current element is
// less than or equal to sum
if (A[ind] <= sum) {
// Count subsequences excluding
// the current element
dp[ind][sum]
= countSubsequenceUtil(
ind + 1,
sum, A, N, dp)
+
// Count subsequences including
// the current element
countSubsequenceUtil(
ind + 1,
sum - A[ind],
A, N, dp);
}
else {
// Exclude current element
dp[ind][sum]
= countSubsequenceUtil(
ind + 1,
sum, A,
N, dp);
}
// Return the result
return dp[ind][sum];
} // Function to return the count of subsequence // in an array with sum less than or equal to X int countSubsequence( int * A, int N, int X)
{ // Initialize a DP array
vector<vector< int > > dp(
N,
vector< int >(X + 1, -1));
// Return the result
return countSubsequenceUtil(0, X, A,
N, dp)
- 1;
} // Driver Code int main()
{ int arr[] = { 25, 13, 40 }, X = 50;
int N = sizeof (arr) / sizeof (arr[0]);
cout << countSubsequence(arr, N, X);
return 0;
} |
// Java program to count number // of subsequences in an array // with sum less than or equal to X class GFG{
// Utility function to return the count // of subsequence in an array with sum // less than or equal to X static int countSubsequenceUtil( int ind, int sum,
int []A, int N,
int [][]dp)
{ // Base condition
if (ind == N)
return 1 ;
// Return if the sub-problem
// is already calculated
if (dp[ind][sum] != - 1 )
return dp[ind][sum];
// Check if the current element is
// less than or equal to sum
if (A[ind] <= sum)
{
// Count subsequences excluding
// the current element
dp[ind][sum] = countSubsequenceUtil(
ind + 1 , sum,
A, N, dp) +
// Count subsequences
// including the current
// element
countSubsequenceUtil(
ind + 1 ,
sum - A[ind],
A, N, dp);
}
else
{
// Exclude current element
dp[ind][sum] = countSubsequenceUtil(
ind + 1 , sum,
A, N, dp);
}
// Return the result
return dp[ind][sum];
} // Function to return the count of subsequence // in an array with sum less than or equal to X static int countSubsequence( int [] A, int N, int X)
{ // Initialize a DP array
int [][]dp = new int [N][X + 1 ];
for ( int i = 0 ; i < N; i++)
{
for ( int j = 0 ; j < X + 1 ; j++)
{
dp[i][j] = - 1 ;
}
}
// Return the result
return countSubsequenceUtil( 0 , X, A,
N, dp) - 1 ;
} // Driver Code public static void main(String[] args)
{ int arr[] = { 25 , 13 , 40 }, X = 50 ;
int N = arr.length;
System.out.print(countSubsequence(arr, N, X));
} } // This code is contributed by Rajput-Ji |
# Python program for the above approach: ## Utility function to return the count ## of subsequence in an array with sum ## less than or equal to X def countSubsequenceUtil(ind, s, A, N, dp):
## Base condition
if (ind = = N):
return 1
## Return if the sub-problem
## is already calculated
if (dp[ind][s] ! = - 1 ):
return dp[ind][s]
## Check if the current element is
## less than or equal to sum
if (A[ind] < = s):
## Count subsequences excluding
## the current element
## Also, Count subsequences including
## the current element
dp[ind][s] = countSubsequenceUtil(ind + 1 , s, A, N, dp) + countSubsequenceUtil(ind + 1 , s - A[ind], A, N, dp)
else :
## Exclude current element
dp[ind][s] = countSubsequenceUtil(ind + 1 , s, A, N, dp)
## Return the result
return dp[ind][s]
## Function to return the count of subsequence ## in an array with sum less than or equal to X def countSubsequence(A, N, X):
## Initialize a DP array
dp = [[ - 1 for _ in range (X + 1 )] for i in range (N)]
## Return the result
return countSubsequenceUtil( 0 , X, A, N, dp) - 1
## Driver code if __name__ = = '__main__' :
arr = [ 25 , 13 , 40 ]
X = 50
N = len (arr)
print (countSubsequence(arr, N, X))
|
// C# program to count number // of subsequences in an array // with sum less than or equal to X using System;
class GFG{
// Utility function to return the count // of subsequence in an array with sum // less than or equal to X static int countSubsequenceUtil( int ind, int sum,
int []A, int N,
int [,]dp)
{ // Base condition
if (ind == N)
return 1;
// Return if the sub-problem
// is already calculated
if (dp[ind, sum] != -1)
return dp[ind, sum];
// Check if the current element is
// less than or equal to sum
if (A[ind] <= sum)
{
// Count subsequences excluding
// the current element
dp[ind, sum] = countSubsequenceUtil(
ind + 1, sum,
A, N, dp) +
// Count subsequences
// including the current
// element
countSubsequenceUtil(
ind + 1,
sum - A[ind],
A, N, dp);
}
else
{
// Exclude current element
dp[ind, sum] = countSubsequenceUtil(
ind + 1, sum,
A, N, dp);
}
// Return the result
return dp[ind, sum];
} // Function to return the count of subsequence // in an array with sum less than or equal to X static int countSubsequence( int [] A, int N, int X)
{ // Initialize a DP array
int [,]dp = new int [N, X + 1];
for ( int i = 0; i < N; i++)
{
for ( int j = 0; j < X + 1; j++)
{
dp[i, j] = -1;
}
}
// Return the result
return countSubsequenceUtil(0, X, A,
N, dp) - 1;
} // Driver Code public static void Main(String[] args)
{ int []arr = { 25, 13, 40 };
int X = 50;
int N = arr.Length;
Console.Write(countSubsequence(arr, N, X));
} } // This code is contributed by 29AjayKumar |
<script> // JavaScript program to count number // of subsequences in an array // with sum less than or equal to X // Utility function to return the count // of subsequence in an array with sum // less than or equal to X function countSubsequenceUtil(ind, sum, A, N, dp)
{ // Base condition
if (ind == N)
return 1;
// Return if the sub-problem
// is already calculated
if (dp[ind][sum] != -1)
return dp[ind][sum];
// Check if the current element is
// less than or equal to sum
if (A[ind] <= sum)
{
// Count subsequences excluding
// the current element
dp[ind][sum] = countSubsequenceUtil(
ind + 1, sum,
A, N, dp) +
// Count subsequences
// including the current
// element
countSubsequenceUtil(
ind + 1,
sum - A[ind],
A, N, dp);
}
else
{
// Exclude current element
dp[ind][sum] = countSubsequenceUtil(
ind + 1, sum,
A, N, dp);
}
// Return the result
return dp[ind][sum];
} // Function to return the count of subsequence // in an array with sum less than or equal to X function countSubsequence(A, N, X)
{ // Initialize a DP array
let dp = new Array(N);
for ( var i = 0; i < dp.length; i++)
{
dp[i] = new Array(2);
}
for (let i = 0; i < N; i++)
{
for (let j = 0; j < X + 1; j++)
{
dp[i][j] = -1;
}
}
// Return the result
return countSubsequenceUtil(0, X, A,
N, dp) - 1;
} // Driver Code let arr = [ 25, 13, 40 ], X = 50; let N = arr.length; document.write(countSubsequence(arr, N, X)); // This code is contributed by susmitakundugoaldanga </script> |
4
Time Complexity: O(N*X)
Auxiliary Space: O(N*X)
Efficient approach: Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.
Steps to solve this problem :
- Create a DP to store the solution of the subproblems.
- Initialize the DP with base cases when index = n then dp[i][j] = 1.
- Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP.
- Return the final solution stored in dp[0][x] – 1.
Implementation :
// C++ program for above approach #include <bits/stdc++.h> using namespace std;
int countSubsequence( int * A, int N, int X)
{ // Initialize a DP array
int dp[N+1][X+1];
memset (dp, 0, sizeof (dp));
// Set Base Case
for ( int i=0 ; i<=N ;i++){
for ( int j=0 ;j<=X ; j++){
if (i==N){
dp[i][j] = 1;
}
}
}
// Fill the DP table
// iterate over subproblems and get the current
// solution for previous computations
for ( int i=N-1; i>=0; i--) {
for ( int j=1; j<=X; j++) {
// update current value
if (A[i] <= j) { // Fixed index here
dp[i][j] = dp[i+1][j] + dp[i+1][j-A[i]];
} else {
dp[i][j] = dp[i+1][j];
}
}
}
// Return the result
return dp[0][X] -1;
} // Driver Code int main()
{ int arr[] = { 25, 13, 40 }, X = 50;
int N = sizeof (arr) / sizeof (arr[0]);
// function call
cout << countSubsequence(arr, N, X);
return 0;
} // This code is contributed by bhardwajji. |
import java.util.*;
public class Main {
public static void main(String[] args) {
int [] arr = { 25 , 13 , 40 };
int X = 50 ;
int N = arr.length;
System.out.println(countSubsequence(arr, N, X));
}
public static int countSubsequence( int [] A, int N, int X) {
// Initialize a DP array
int [][] dp = new int [N+ 1 ][X+ 1 ];
for ( int [] row : dp) {
Arrays.fill(row, 0 );
}
// Set Base Case
for ( int i = 0 ; i <= N; i++) {
for ( int j = 0 ; j <= X; j++) {
if (i == N) {
dp[i][j] = 1 ;
}
}
}
// Fill the DP table
// iterate over subproblems and get the current
// solution for previous computations
for ( int i = N- 1 ; i >= 0 ; i--) {
for ( int j = 1 ; j <= X; j++) {
// update current value
if (A[i] <= j) {
dp[i][j] = dp[i+ 1 ][j] + dp[i+ 1 ][j-A[i]];
} else {
dp[i][j] = dp[i+ 1 ][j];
}
}
}
// Return the result
return dp[ 0 ][X] - 1 ;
}
} |
def countSubsequence(A, N, X):
# Initialize a DP array
dp = [[ 0 for j in range (X + 1 )] for i in range (N + 1 )]
# Set Base Case
for i in range (N + 1 ):
for j in range (X + 1 ):
if i = = N:
dp[i][j] = 1
# Fill the DP table
# iterate over subproblems and get the current
# solution for previous computations
for i in range (N - 1 , - 1 , - 1 ):
for j in range ( 1 , X + 1 ):
# update current value
if A[i] < = j:
dp[i][j] = dp[i + 1 ][j] + dp[i + 1 ][j - A[i]]
else :
dp[i][j] = dp[i + 1 ][j]
# Return the result
return dp[ 0 ][X] - 1
# Driver Code arr = [ 25 , 13 , 40 ]
X = 50
N = len (arr)
# function call print (countSubsequence(arr, N, X))
|
using System;
class Program {
// Function to count subsequences of an array with sum X
static int CountSubsequence( int [] A, int N, int X)
{
// Initialize a DP array
int [, ] dp = new int [N + 1, X + 1];
for ( int i = 0; i <= N; i++) {
for ( int j = 0; j <= X; j++) {
dp[i, j] = 0;
}
}
// Set Base Case
for ( int i = 0; i <= N; i++) {
for ( int j = 0; j <= X; j++) {
if (i == N) {
dp[i, j] = 1;
}
}
}
// Fill the DP table
// iterate over subproblems and get the current
// solution for previous computations
for ( int i = N - 1; i >= 0; i--) {
for ( int j = 1; j <= X; j++) {
// update current value
if (A[i] <= j) // Fixed index here
{
dp[i, j] = dp[i + 1, j]
+ dp[i + 1, j - A[i]];
}
else {
dp[i, j] = dp[i + 1, j];
}
}
}
// Return the result
return dp[0, X] - 1;
}
static void Main( string [] args)
{
int [] arr = { 25, 13, 40 };
int X = 50;
int N = arr.Length;
// function call
Console.WriteLine(CountSubsequence(arr, N, X));
}
} |
function countSubsequence(A, N, X) {
// Initialize a DP array
const dp = Array.from({ length: N + 1 }, () => Array(X + 1).fill(0));
// Set Base Case
for (let i = 0; i <= N; i++) {
for (let j = 0; j <= X; j++) {
if (i === N) {
dp[i][j] = 1;
}
}
}
// Fill the DP table
// iterate over subproblems and get the current
// solution for previous computations
for (let i = N - 1; i >= 0; i--) {
for (let j = 1; j <= X; j++) {
// update current value
if (A[i] <= j) {
dp[i][j] = dp[i + 1][j] + dp[i + 1][j - A[i]];
} else {
dp[i][j] = dp[i + 1][j];
}
}
}
// Return the result
return dp[0][X] - 1;
} // Driver Code const arr = [25, 13, 40]; const X = 50; const N = arr.length; // function call console.log(countSubsequence(arr, N, X)); // This code is contributed by Samim Hossain Mondal. |
4
Time Complexity: O(N*X)
Auxiliary Space: O(N*X)