Skip to content
Related Articles
Get the best out of our app
GFG App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Count of subsequences of Array with last digit of product as K

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

Given an array A[] of size N and a digit K. Find the number of sub-sequences of the array where the last digit of the product of the elements of the sub-sequence is K.

Example:

Input:  A = {2, 3, 4, 2}, K = 2
Output: 4
Explanation:  sub-sequences with product’s last digit = 2 are: {2}, {2}, {2, 3, 2}, {3, 4}

Input: A = {1, 1, 1, 2}, K = 1
Output: 7
Explanation: The sub-sequences with product’s last digit = 2 are: {1}, {1}, {1}, {1, 1}, {1, 1}, {1, 1},  {1, 1, 1}

 

Approach: The above problem can be solved using recursion based on below idea:

We will use the recursive approach to find each possible sub-sequences, and on the go we will calculate the product of the elements and keep track of the last digit p, then at end we check if p is equal to K we return 1 else return 0. 

Illustration:

Note: during multiplication of two numbers say a = 133 and b = 26
 133
x 26
——
1798   <— last digit gets multiplied only once
266X
——
3458   (3*6 = 18,  both have 8 as last digits)
So the last digit of the a*b will be equal to the last digit of product of last digits of a and b 
Suppose we have numbers 11, 233, 783, 4759, 6
product of the numbers = 57302995266
product of just the last digits, i.e., 1, 3, 3, 9, 6 = 486
Both have last digit as 6 

Follow the below steps to solve the problem:

  • Base Case: if p is equal to K return 1, else return 0
  • There are two options either take the element or don’t.
    • if we take the element, then the product p gets updated to p*a[n-1], as we are just bothered about the last digit so we can just update p to the last digit of p*a[n-1], i.e., p becomes p*a[n-1]%10.
    • other option is don’t take the element, so don’t update p and do n-1, to look for other possibilities.
  • As we need the total number of such sub-sequences we return the sum of the above two calls.
  • An edge case is if K=1, then we will get one extra sub-sequence that is an empty sub-sequence, as we initially take p=1 so in an empty sub-sequence we get p==k and 1 is returned. So when K==1 we deduct 1 from the answer. 

Time Complexity:  O(2N)
Auxiliary Space:  O(N)

Efficient Approach: Since Recursion takes exponential time complexity, the above recursive approach can be optimized further using Dynamic Programming. We will construct a look-up table and memoize the recursive code in order to do so.

Below is the implementation of the above approach:

C++




// C++ program for Count the number of
// sub-sequences of an  array where the last digit
// of the product of the subsequence is K.
#include <bits/stdc++.h>
using namespace std;
 
int dp[1001][10];
// recursive utility function
int countSubsequencesUtil(int n, int k, int p,
                          vector<int>& a)
{
    // Base case
    if (n == 0) {
        if (p == k)
            return 1;
        else
            return 0;
    }
 
    // return pre calculated value from
    // look-up table
    if (dp[n][p] != -1)
        return dp[n][p];
 
    // return the total number obtained through
    // option1 and option2
    return dp[n][p]
           = countSubsequencesUtil(n - 1, k,
                                   (p * a[n - 1]) % 10, a)
             + countSubsequencesUtil(n - 1, k, p, a);
}
// Function to  Count the number of subsequences
int countSubsequences(vector<int>& a, int k)
{
    // initialize the table with -1
    memset(dp, -1, sizeof(dp));
 
    int n = a.size();
    int ans = countSubsequencesUtil(n, k, 1, a);
 
    // if k is 1 return 1 less
    if (k == 1)
        return ans - 1;
 
    return ans;
}
 
// Driver Code
int main()
{
    vector<int> a = { 2, 3, 4, 2 };
    int k = 2;
 
    cout << countSubsequences(a, k);
 
    return 0;
}


Java




// Java program to count the number of subsequences
// of an array where the last digit of the product
// of the subsequence is K
import java.io.*;
import java.util.*;
 
public class GFG {
 
  static int[][] dp = new int[1001][10];
 
  // recursive utility function
  static int countSubsequencesUtil(int n, int k, int p,
                                   int[] a)
  {
    // base case
    if (n == 0) {
      if (p == k)
        return 1;
      return 0;
    }
 
    // return pre calculated value from
    // look up table
    if (dp[n][p] != -1)
      return dp[n][p];
 
    // return the total no. obtained through
    // option1 and option2
    return dp[n][p]
      = countSubsequencesUtil(n - 1, k,
                              (p * a[n - 1]) % 10, a)
      + countSubsequencesUtil(n - 1, k, p, a);
  }
 
  // function to count the number of subsequences
  static int countSubsequences(int[] a, int k)
  {
 
    // initializing all elements of table with -1
    for (int i = 0; i <= 1000; i++) {
      for (int j = 0; j < 10; j++) {
        dp[i][j] = -1;
      }
    }
 
    int n = a.length;
    int ans = countSubsequencesUtil(n, k, 1, a);
 
    // if k is 1 return 1 less
    if (k == 1)
      return ans - 1;
 
    return ans;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int[] a = { 2, 3, 4, 2 };
    int k = 2;
    System.out.print(countSubsequences(a, k));
  }
}
 
// This code is contributed by phasing17


Python3




# Python implementation of above approach
dp = [[-1]*10]*1001
 
# recursive utility function
def countSubsequencesUtil(n, k, p, a) :
     
    # Base case
    if (n == 0) :
        if (p == k):
            return 1
        else:
            return 0
     
    # return pre calculated value from
    # look-up table
    if (dp[n][p] != -1):
        return dp[n][p]
 
    # return the total number obtained through
    # option1 and option2
    dp[n][p] = (countSubsequencesUtil(n - 1, k,(p * a[n - 1]) % 10, a) +
                    countSubsequencesUtil(n - 1, k, p, a));
    return (dp[n][p]);
 
# Function to  Count the number of subsequences
def countSubsequences(a, k) :
 
    n = len(a)
    ans = countSubsequencesUtil(n, k, 1, a)
 
    # if k is 1 return 1 less
    if (k == 1) :
        return (ans - 1)
 
    return ans + 1
 
# Driver Code
a = [ 2, 3, 4, 2 ]
k = 2
 
print(countSubsequences(a, k))
 
# This code is contributed by sanjoy_62.


C#




// C# program for Count the number of
// sub-sequences of an  array where the last digit
// of the product of the subsequence is K.
using System;
class GFG {
 
    static int[, ] dp = new int[1001, 10];
    // recursive utility function
    static int countSubsequencesUtil(int n, int k, int p,
                                     int[] a)
    {
        // Base case
        if (n == 0) {
            if (p == k)
                return 1;
            else
                return 0;
        }
 
        // return pre calculated value from
        // look-up table
        if (dp[n, p] != -1)
            return dp[n, p];
 
        // return the total number obtained through
        // option1 and option2
        return dp[n, p]
            = countSubsequencesUtil(n - 1, k,
                                    (p * a[n - 1]) % 10, a)
              + countSubsequencesUtil(n - 1, k, p, a);
    }
    // Function to  Count the number of subsequences
    static int countSubsequences(int[] a, int k)
    {
        // initialize the table with -1
        for (int i = 0; i < 1001; i++) {
            for (int j = 0; j < 10; j++) {
                dp[i, j] = -1;
            }
        }
 
        int n = a.Length;
        int ans = countSubsequencesUtil(n, k, 1, a);
 
        // if k is 1 return 1 less
        if (k == 1)
            return ans - 1;
 
        return ans;
    }
 
    // Driver Code
    public static void Main()
    {
        int[] a = { 2, 3, 4, 2 };
        int k = 2;
 
        Console.Write(countSubsequences(a, k));
    }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript




<script>
 
// JavaScript program for Count the number of
// sub-sequences of an  array where the last digit
// of the product of the subsequence is K.
 
// initialize the dp table with -1
let dp = new Array(1001)
for(let i = 0; i < 1001; i++)
{
    dp[i] = new Array(10).fill(-1)
}
 
// recursive utility function
function countSubsequencesUtil(n, k, p,a)
{
    // Base case
    if (n == 0) {
        if (p == k)
            return 1
        else
            return 0
    }
 
    // return pre calculated value from
    // look-up table
    if (dp[n][p] != -1)
        return dp[n][p]
 
    // return the total number obtained through
    // option1 and option2
    return dp[n][p] = countSubsequencesUtil(n - 1, k, (p * a[n - 1]) % 10, a) + countSubsequencesUtil(n - 1, k, p, a)
}
 
// Function to  Count the number of subsequences
function countSubsequences(a,k)
{
 
    let n = a.length
    let ans = countSubsequencesUtil(n, k, 1, a)
 
    // if k is 1 return 1 less
    if (k == 1)
        return ans - 1;
 
    return ans;
}
 
// Driver Code
let a = [ 2, 3, 4, 2 ]
let k = 2
 
document.write(countSubsequences(a, k))
 
// This code is contributed by shinjanpatra.
</script>


Output

4

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

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 + memorization(top-down) because memorization method needs extra stack space of recursion calls.

Steps to solve this problem :

  • Create a table to store the solution of the subproblems.
  • Initialize the table with base cases
  • Fill up the table iteratively
  • Return the final solution

Implementation :

C++




// C++ program to count the number of subsequences
// of an array where the last digit of the product
// of the subsequence is k
#include <bits/stdc++.h>
using namespace std;
 
int dp[1001][10];
 
// Function to count the number of subsequences
int countSubsequences(vector<int>& a, int k)
{
    int n = a.size();
 
    // Initialize dp table
    for (int i = 0; i < n; i++) {
        // mark the element's remainder with 10 as 1
        dp[i][a[i] % 10] = 1;
    }
 
    // Fill dp table
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < 10; j++) {
            // add the results of previous cells
            dp[i][j] += dp[i - 1][j] + dp[i - 1][(j * a[i]) % 10];
        }
    }
 
    // Return answer
    return dp[n - 1][k];
}
 
// Driver code
int main()
{
    vector<int> a = { 2, 3, 4, 2 };
    int k = 2;
    // function
    cout << countSubsequences(a, k);
 
    return 0;
}
 
// this code is contributed by bhardwajji


Java




import java.util.*;
 
public class Main {
    static int[][] dp = new int[1001][10];
 
    // Function to count the number of subsequences
    static int countSubsequences(List<Integer> a, int k) {
        int n = a.size();
 
        // Initialize dp table
        for (int i = 0; i < n; i++) {
            // mark the element's remainder with 10 as 1
            dp[i][a.get(i) % 10] = 1;
        }
 
        // Fill dp table
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < 10; j++) {
                // add the results of previous cells
                dp[i][j] += dp[i - 1][j] + dp[i - 1][(j * a.get(i)) % 10];
            }
        }
 
        // Return answer
        return dp[n - 1][k];
    }
 
    public static void main(String[] args) {
        List<Integer> a = Arrays.asList(2, 3, 4, 2);
        int k = 2;
        // function call
        System.out.println(countSubsequences(a, k));
    }
}


Python3




# Function to count the number of subsequences
def count_subsequences(a, k):
    n = len(a)
    dp = [[0] * 10 for i in range(n)]
 
    # Initialize dp table
    for i in range(n):
        # mark the element's remainder with 10 as 1
        dp[i][a[i] % 10] = 1
 
    # Fill dp table
    for i in range(1, n):
        for j in range(10):
            # add the results of previous cells
            dp[i][j] += dp[i - 1][j] + dp[i - 1][(j * a[i]) % 10]
 
    # Return answer
    return dp[n - 1][k]
 
# Driver code
a = [2, 3, 4, 2]
k = 2
 
# function call
print(count_subsequences(a, k))


C#




using System;
using System.Collections.Generic;
 
public class MainClass {
static int[,] dp = new int[1001, 10];
 // Function to count the number of subsequences
static int CountSubsequences(List<int> a, int k) {
    int n = a.Count;
 
    // Initialize dp table
    for (int i = 0; i < n; i++) {
        // mark the element's remainder with 10 as 1
        dp[i, a[i] % 10] = 1;
    }
 
    // Fill dp table
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < 10; j++) {
            // add the results of previous cells
            dp[i, j] += dp[i - 1, j] + dp[i - 1, (j * a[i]) % 10];
        }
    }
 
    // Return answer
    return dp[n - 1, k];
}
 
public static void Main(string[] args) {
    List<int> a = new List<int>() {2, 3, 4, 2};
    int k = 2;
 
    // function call
    Console.WriteLine(CountSubsequences(a, k));
}
}


Javascript




// Function to count the number of subsequences
function count_subsequences(a, k) {
    let n = a.length;
    let dp = Array.from(Array(n), () => Array(10).fill(0));
 
    // Initialize dp table
    for (let i = 0; i < n; i++) {
        // mark the element's remainder with 10 as 1
        dp[i][a[i] % 10] = 1;
    }
 
    // Fill dp table
    for (let i = 1; i < n; i++) {
        for (let j = 0; j < 10; j++) {
            // add the results of previous cells
            dp[i][j] += dp[i - 1][j] + dp[i - 1][(j * a[i]) % 10];
        }
    }
 
    // Return answer
    return dp[n - 1][k];
}
 
// Driver code
let a = [2, 3, 4, 2];
let k = 2;
 
// function call
console.log(count_subsequences(a, k));


Output :

4

Time complexity: O(n * 10), where n is the length of the input array.
Auxiliary Space:  O(n * 10).


My Personal Notes arrow_drop_up
Last Updated : 30 Mar, 2023
Like Article
Save Article
Similar Reads
Related Tutorials