Monday, November 18, 2024
Google search engine
HomeLanguagesDynamic ProgrammingCount all increasing subsequences

Count all increasing subsequences

We are given an array of digits (values lie in range from 0 to 9). The task is to count all the sub sequences possible in array such that in each subsequence every digit is greater than its previous digits in the subsequence.

Examples: 

Input : arr[] = {1, 2, 3, 4}
Output: 15
There are 15 increasing subsequences
{1}, {2}, {3}, {4}, {1,2}, {1,3}, {1,4}, 
{2,3}, {2,4}, {3,4}, {1,2,3}, {1,2,4}, 
{1,3,4}, {2,3,4}, {1,2,3,4}

Input : arr[] = {4, 3, 6, 5}
Output: 8
Sub-sequences are {4}, {3}, {6}, {5}, 
{4,6}, {4,5}, {3,6}, {3,5}

Input : arr[] = {3, 2, 4, 5, 4}
Output : 15
Sub-sequences are {3}, {2}, {4}, {3,4},
{2,4}, {5}, {3,5}, {2,5}, {4,5}, {3,2,5}
{3,4,5},{2,4,5},{4}, {3,4}, {2,4}

A Simple Solution is to use Dynamic Programming Solution of Longest Increasing Subsequence (LIS) problem. Like LIS problem, we first compute count of increasing subsequences ending at every index. Finally, we return sum of all values (In LCS problem, we return max of all values).

// We count all increasing subsequences ending at every 
// index i
subCount(i) = Count of increasing subsequences ending 
              at arr[i]. 

// Like LCS, this value can be recursively computed
subCount(i) = 1 + ? subCount(j) 
              where j is index of all elements
              such that arr[j] < arr[i] and j < i.
1 is added as every element itself is a subsequence
of size 1.

// Finally we add all counts to get the result.
Result = ? subCount(i)
         where i varies from 0 to n-1.

Illustration: 

For example, arr[] = {3, 2, 4, 5, 4}

// There are no smaller elements on left of arr[0] 
// and arr[1]
subCount(0) = 1
subCount(1) = 1  

// Note that arr[0] and arr[1] are smaller than arr[2]
subCount(2) = 1 + subCount(0) + subCount(1)  = 3

subCount(3) = 1 + subCount(0) + subCount(1) + subCount(2) 
            = 1 + 1 + 1 + 3
            = 6
  
subCount(3) = 1 + subCount(0) + subCount(1)
            = 1 + 1 + 1
            = 3
                             
Result = subCount(0) + subCount(1) + subCount(2) + subCount(3)
       = 1 + 1 + 3 + 6 + 3
       = 14.

Time Complexity : O(n2
Auxiliary Space : O(n)

Refer this for implementation.

Method 2 (Efficient) 

The above solution doesn’t use the fact that we have only 10 possible values in given array. We can use this fact by using an array count[] such that count[d] stores current count digits smaller than d. 

For example, arr[] = {3, 2, 4, 5, 4}

// We create a count array and initialize it as 0.
count[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

// Note that here value is used as index to store counts
count[3] += 1  // i = 0, arr[0] = 3
          = 1    
count[2] += 1  // i = 1, arr[1] = 2
          = 1
          
// Let us compute count for arr[2] which is 4
count[4] += 1 + count[3] + count[2] 
         += 1 + 1 + 1  
         = 3

// Let us compute count for arr[3] which is 5
count[5] += 1 + count[3] + count[2] + count[4] 
         += 1 + 1 + 1 + 3
         = 6

// Let us compute count for arr[4] which is 4
count[4] += 1 + count[0] + count[1]
         += 1 + 1 + 1
         += 3
         = 3 + 3
         = 6
            
Note that count[] = {0, 0, 1, 1, 6, 6, 0, 0, 0, 0}                  
Result = count[0] + count[1] + ... + count[9]
       = 1 + 1 + 6 + 6 {count[2] = 1, count[3] = 1
                        count[4] = 6, count[5] = 6} 
       = 14

Below is the implementation of above idea. 

C++




// C++ program to count increasing subsequences
// in an array of digits.
#include<bits/stdc++.h>
using namespace std;
 
// Function To Count all the sub-sequences
// possible in which digit is greater than
// all previous digits arr[] is array of n
// digits
int countSub(int arr[], int n)
{
    // count[] array is used to store all sub-
    // sequences possible using that digit
    // count[] array covers all the digit
    // from 0 to 9
    int count[10] = {0};
 
    // scan each digit in arr[]
    for (int i=0; i<n; i++)
    {
        // count all possible sub-sequences by
        // the digits less than arr[i] digit
        for (int j=arr[i]-1; j>=0; j--)
            count[arr[i]] += count[j];
 
        // store sum of all sub-sequences plus
        // 1 in count[] array
        count[arr[i]]++;
    }
 
    // now sum up the all sequences possible in
    // count[] array
    int result = 0;
    for (int i=0; i<10; i++)
        result += count[i];
 
    return result;
}
 
// Driver program to run the test case
int main()
{
    int arr[] = {3, 2, 4, 5, 4};
    int n = sizeof(arr)/sizeof(arr[0]);
 
    cout << countSub(arr,n);
    return 0;
}


Java




// Java program to count increasing
// subsequences in an array of digits.
import java.io.*;
 
class GFG {
 
    // Function To Count all the sub-sequences
    // possible in which digit is greater than
    // all previous digits arr[] is array of n
    // digits
    static int countSub(int arr[], int n)
    {
        // count[] array is used to store all
        // sub-sequences possible using that
        // digit count[] array covers all
        // the digit from 0 to 9
        int count[] = new int[10]; 
 
        // scan each digit in arr[]
        for (int i = 0; i < n; i++)
        {
            // count all possible sub-
            // sequences by the digits
            // less than arr[i] digit
            for (int j = arr[i] - 1; j >= 0; j--)
                count[arr[i]] += count[j]; 
                 
            // store sum of all sub-sequences
            // plus 1 in count[] array
            count[arr[i]]++;
        }  
 
        // now sum up the all sequences
        // possible in count[] array
        int result = 0;
        for (int i = 0; i < 10; i++)
            result += count[i];
 
        return result;
    }
 
    // Driver program to run the test case
    public static void main(String[] args)
    {
        int arr[] = {3, 2, 4, 5, 4};
        int n = arr.length;
 
        System.out.println(countSub(arr,n));
    }
}
// This code is contributed by Prerna Saini


Python3




# Python3 program to count increasing
# subsequences in an array of digits.
 
# Function To Count all the sub-
# sequences possible in which digit
# is greater than all previous digits
# arr[] is array of n digits
def countSub(arr, n):
 
    # count[] array is used to store all
    # sub-sequences possible using that
    # digit count[] array covers all the
    # digit from 0 to 9
    count = [0 for i in range(10)]
 
    # scan each digit in arr[]
    for i in range(n):
     
        # count all possible sub-sequences by
        # the digits less than arr[i] digit
        for j in range(arr[i] - 1, -1, -1):
            count[arr[i]] += count[j]
 
        # store sum of all sub-sequences
        # plus 1 in count[] array
        count[arr[i]] += 1
     
 
    # Now sum up the all sequences
    # possible in count[] array
    result = 0
    for i in range(10):
        result += count[i]
 
    return result
 
# Driver Code
arr = [3, 2, 4, 5, 4]
n = len(arr)
print(countSub(arr, n))
 
# This code is contributed by Anant Agarwal.


C#




// C# program to count increasing
// subsequences in an array of digits.
using System;
class GFG {
 
    // Function To Count all the sub-sequences
    // possible in which digit is greater than
    // all previous digits arr[] is array of n
    // digits
    static int countSub(int []arr, int n)
    {
        // count[] array is used to store all
        // sub-sequences possible using that
        // digit count[] array covers all
        // the digit from 0 to 9
        int []count = new int[10]; 
 
        // scan each digit in arr[]
        for (int i = 0; i < n; i++)
        {
            // count all possible sub-
            // sequences by the digits
            // less than arr[i] digit
            for (int j = arr[i] - 1; j >= 0; j--)
                count[arr[i]] += count[j]; 
                 
            // store sum of all sub-sequences
            // plus 1 in count[] array
            count[arr[i]]++;
        }  
 
        // now sum up the all sequences
        // possible in count[] array
        int result = 0;
        for (int i = 0; i < 10; i++)
            result += count[i];
 
        return result;
    }
 
    // Driver program
    public static void Main()
    {
        int []arr = {3, 2, 4, 5, 4};
        int n = arr.Length;
 
        Console.WriteLine(countSub(arr,n));
    }
}
// This code is contributed by Anant Agarwal.


Javascript




<script>
 
// Javascript program to count increasing
// subsequences in an array of digits.
 
// Function To Count all the sub-sequences
// possible in which digit is greater than
// all previous digits arr[] is array of n
// digits
function countSub(arr, n)
{
     
    // count[] array is used to store all sub-
    // sequences possible using that digit
    // count[] array covers all the digit
    // from 0 to 9
    let count = new Array(10).fill(0);
 
    // Scan each digit in arr[]
    for(let i = 0; i < n; i++)
    {
         
        // Count all possible sub-sequences by
        // the digits less than arr[i] digit
        for(let j = arr[i] - 1; j >= 0; j--)
            count[arr[i]] += count[j];
 
        // Store sum of all sub-sequences plus
        // 1 in count[] array
        count[arr[i]]++;
    }
 
    // Now sum up the all sequences possible in
    // count[] array
    let result = 0;
    for(let i = 0; i < 10; i++)
        result += count[i];
 
    return result;
}
 
// Driver code
let arr = [ 3, 2, 4, 5, 4 ];
let n = arr.length;
 
document.write(countSub(arr, n));
 
// This code is contributed by _saurabh_jaiswal
 
</script>


Output

14

Time Complexity : O(n) Note that the inner loop runs at most 10 times. 
Auxiliary Space : O(1) Note that count has at-most 10 elements.

This article is contributed by Shashank Mishra ( Gullu ). If you like neveropen and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the neveropen main page and help other Geeks. 

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 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments