Count of subsequences in an array with sum less than or equal to X
Last Updated :
01 Sep, 2023
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++
#include <bits/stdc++.h>
using namespace std;
int countSubsequenceUtil(
int ind, int sum,
int * A, int N,
vector<vector< int > >& dp)
{
if (ind == N)
return 1;
if (dp[ind][sum] != -1)
return dp[ind][sum];
if (A[ind] <= sum) {
dp[ind][sum]
= countSubsequenceUtil(
ind + 1,
sum, A, N, dp)
+
countSubsequenceUtil(
ind + 1,
sum - A[ind],
A, N, dp);
}
else {
dp[ind][sum]
= countSubsequenceUtil(
ind + 1,
sum, A,
N, dp);
}
return dp[ind][sum];
}
int countSubsequence( int * A, int N, int X)
{
vector<vector< int > > dp(
N,
vector< int >(X + 1, -1));
return countSubsequenceUtil(0, X, A,
N, dp)
- 1;
}
int main()
{
int arr[] = { 25, 13, 40 }, X = 50;
int N = sizeof (arr) / sizeof (arr[0]);
cout << countSubsequence(arr, N, X);
return 0;
}
|
Java
class GFG{
static int countSubsequenceUtil( int ind, int sum,
int []A, int N,
int [][]dp)
{
if (ind == N)
return 1 ;
if (dp[ind][sum] != - 1 )
return dp[ind][sum];
if (A[ind] <= sum)
{
dp[ind][sum] = countSubsequenceUtil(
ind + 1 , sum,
A, N, dp) +
countSubsequenceUtil(
ind + 1 ,
sum - A[ind],
A, N, dp);
}
else
{
dp[ind][sum] = countSubsequenceUtil(
ind + 1 , sum,
A, N, dp);
}
return dp[ind][sum];
}
static int countSubsequence( int [] A, int N, int X)
{
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 countSubsequenceUtil( 0 , X, A,
N, dp) - 1 ;
}
public static void main(String[] args)
{
int arr[] = { 25 , 13 , 40 }, X = 50 ;
int N = arr.length;
System.out.print(countSubsequence(arr, N, X));
}
}
|
Python3
def countSubsequenceUtil(ind, s, A, N, dp):
if (ind = = N):
return 1
if (dp[ind][s] ! = - 1 ):
return dp[ind][s]
if (A[ind] < = s):
dp[ind][s] = countSubsequenceUtil(ind + 1 , s, A, N, dp) + countSubsequenceUtil(ind + 1 , s - A[ind], A, N, dp)
else :
dp[ind][s] = countSubsequenceUtil(ind + 1 , s, A, N, dp)
return dp[ind][s]
def countSubsequence(A, N, X):
dp = [[ - 1 for _ in range (X + 1 )] for i in range (N)]
return countSubsequenceUtil( 0 , X, A, N, dp) - 1
if __name__ = = '__main__' :
arr = [ 25 , 13 , 40 ]
X = 50
N = len (arr)
print (countSubsequence(arr, N, X))
|
C#
using System;
class GFG{
static int countSubsequenceUtil( int ind, int sum,
int []A, int N,
int [,]dp)
{
if (ind == N)
return 1;
if (dp[ind, sum] != -1)
return dp[ind, sum];
if (A[ind] <= sum)
{
dp[ind, sum] = countSubsequenceUtil(
ind + 1, sum,
A, N, dp) +
countSubsequenceUtil(
ind + 1,
sum - A[ind],
A, N, dp);
}
else
{
dp[ind, sum] = countSubsequenceUtil(
ind + 1, sum,
A, N, dp);
}
return dp[ind, sum];
}
static int countSubsequence( int [] A, int N, int X)
{
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 countSubsequenceUtil(0, X, A,
N, dp) - 1;
}
public static void Main(String[] args)
{
int []arr = { 25, 13, 40 };
int X = 50;
int N = arr.Length;
Console.Write(countSubsequence(arr, N, X));
}
}
|
Javascript
<script>
function countSubsequenceUtil(ind, sum, A, N, dp)
{
if (ind == N)
return 1;
if (dp[ind][sum] != -1)
return dp[ind][sum];
if (A[ind] <= sum)
{
dp[ind][sum] = countSubsequenceUtil(
ind + 1, sum,
A, N, dp) +
countSubsequenceUtil(
ind + 1,
sum - A[ind],
A, N, dp);
}
else
{
dp[ind][sum] = countSubsequenceUtil(
ind + 1, sum,
A, N, dp);
}
return dp[ind][sum];
}
function countSubsequence(A, N, X)
{
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 countSubsequenceUtil(0, X, A,
N, dp) - 1;
}
let arr = [ 25, 13, 40 ], X = 50;
let N = arr.length;
document.write(countSubsequence(arr, N, X));
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
int countSubsequence( int * A, int N, int X)
{
int dp[N+1][X+1];
memset (dp, 0, sizeof (dp));
for ( int i=0 ; i<=N ;i++){
for ( int j=0 ;j<=X ; j++){
if (i==N){
dp[i][j] = 1;
}
}
}
for ( int i=N-1; i>=0; i--) {
for ( int j=1; j<=X; j++) {
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 dp[0][X] -1;
}
int main()
{
int arr[] = { 25, 13, 40 }, X = 50;
int N = sizeof (arr) / sizeof (arr[0]);
cout << countSubsequence(arr, N, X);
return 0;
}
|
Java
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) {
int [][] dp = new int [N+ 1 ][X+ 1 ];
for ( int [] row : dp) {
Arrays.fill(row, 0 );
}
for ( int i = 0 ; i <= N; i++) {
for ( int j = 0 ; j <= X; j++) {
if (i == N) {
dp[i][j] = 1 ;
}
}
}
for ( int i = N- 1 ; i >= 0 ; i--) {
for ( int j = 1 ; j <= X; j++) {
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 dp[ 0 ][X] - 1 ;
}
}
|
Python3
def countSubsequence(A, N, X):
dp = [[ 0 for j in range (X + 1 )] for i in range (N + 1 )]
for i in range (N + 1 ):
for j in range (X + 1 ):
if i = = N:
dp[i][j] = 1
for i in range (N - 1 , - 1 , - 1 ):
for j in range ( 1 , X + 1 ):
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 dp[ 0 ][X] - 1
arr = [ 25 , 13 , 40 ]
X = 50
N = len (arr)
print (countSubsequence(arr, N, X))
|
C#
using System;
class Program {
static int CountSubsequence( int [] A, int N, int X)
{
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;
}
}
for ( int i = 0; i <= N; i++) {
for ( int j = 0; j <= X; j++) {
if (i == N) {
dp[i, j] = 1;
}
}
}
for ( int i = N - 1; i >= 0; i--) {
for ( int j = 1; j <= X; j++) {
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 dp[0, X] - 1;
}
static void Main( string [] args)
{
int [] arr = { 25, 13, 40 };
int X = 50;
int N = arr.Length;
Console.WriteLine(CountSubsequence(arr, N, X));
}
}
|
Javascript
function countSubsequence(A, N, X) {
const dp = Array.from({ length: N + 1 }, () => Array(X + 1).fill(0));
for (let i = 0; i <= N; i++) {
for (let j = 0; j <= X; j++) {
if (i === N) {
dp[i][j] = 1;
}
}
}
for (let i = N - 1; i >= 0; i--) {
for (let j = 1; j <= X; j++) {
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 dp[0][X] - 1;
}
const arr = [25, 13, 40];
const X = 50;
const N = arr.length;
console.log(countSubsequence(arr, N, X));
|
Time Complexity: O(N*X)
Auxiliary Space: O(N*X)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...