Open In App

Count ways to generate N digit number such that its every digit divisible by previous digit

Last Updated : 16 May, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a number N, the task is to count the number of ways to create an N digit number from digits 1 to 9 such that every digit is divisible by its previous digit that is if the number is represented by an array of digits A then A[i + 1] % A[i] == 0. print the answer modulo 109 + 7.

Examples:

Input: N = 2
Output: 23
Explanation: For N = 2 possible answers are 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 24, 26, 28, 33, 36, 39, 44, 48, 55, 66, 77, 88, and 99.

Input: N = 3
Output:  44 

Naive approach: The basic way to solve the problem is as follows:

The basic way to solve this problem is to generate all possible combinations by using a recursive approach.

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

Efficient Approach:  The above approach can be optimized based on the following idea:

Dynamic programming can be used to solve this problem

  • dp[i][j] represents the number of ways of creating a number of size i and j is its previous digit taken.
  • It can be observed that the recursive function is called exponential times. That means that some states are called repeatedly. 
  • So the idea is to store the value of each state. This can be done by storing the value of a state and whenever the function is called, returning the stored value without computing again.

Follow the steps below to solve the problem:

  • Create a recursive function that takes two parameters representing ith position to be filled and j representing the last digit taken.
  • Call the recursive function for choosing all digits from 1 to 9.
  • Base case if all positions filled return 1.
  • Create a 2d array of dp[N][10] initially filled with -1.
  • If the answer for a particular state is computed then save it in dp[i][j].
  • If the answer for a particular state is already computed then just return dp[i][j].

Below is the implementation of the above approach:

C++




// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
const int MOD = 1e9 + 7;
 
// DP table initialized with -1
int dp[100001][10];
 
// Recursive Function to find number of N
// digits such that its every digit
// divisible by its previous digit
int recur(int i, int j, int N)
{
 
    // Base case
    if (i == N) {
        return 1;
    }
 
    // If answer for current state is
    // already calculated then just
    // return dp[i][j]
    if (dp[i][j] != -1)
        return dp[i][j];
 
    // Answer initialized with zero
    int ans = 0;
 
    // First element to decide
    if (i == 0) {
 
        // Iterating for all digits from
        // 1 to 9
        for (int digit = 1; digit <= 9; digit++) {
 
            // Choosing this as
            // current digit
            ans = (ans + recur(i + 1, digit, N)) % MOD;
        }
    }
 
    // Choosing for other positions apart
    // from first
    else {
 
        // Iterating for all digits
        // from 1 to 9
        for (int digit = 1; digit <= 9; digit++) {
 
            // Choosing this as current
            // digit if it is divisible by
            // previous digit
            if (digit % j == 0)
                ans = (ans + recur(i + 1, digit, N)) % MOD;
        }
    }
 
    // Save and return dp value
    return dp[i][j] = ans;
}
 
// Function to find number of N digits
// such that its every digit divisible
// by its previous digit
int countWays(int N)
{
 
    // Initializing dp array with - 1
    memset(dp, -1, sizeof(dp));
 
    // Calling recursive function for
    // finding answer
    int ans = recur(0, 0, N);
 
    // Returning the answer
    return ans;
}
 
// Driver Code
int main()
{
 
    // Input 1
    int N = 2;
 
    // Function Call
    cout << countWays(N) << endl;
 
    // Input 2
    int N1 = 3;
 
    // Function Call
    cout << countWays(N1) << endl;
    return 0;
}


Java




// Java code to implement the approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
  static final int MOD = (int)1e9 + 7;
  static int[][] dp;
 
  // Recursive Function to find number of N
  // digits such that its every digit
  // divisible by its previous digit
  static int recur(int i, int j, int N)
  {
    // Base case
    if (i == N) {
      return 1;
    }
    // If answer for current state is
    // already calculated then just
    // return dp[i][j]
    if (dp[i][j] != -1) {
      return dp[i][j];
    }
 
    // Answer initialized with zero
    int ans = 0;
 
    // First element to decide
    if (i == 0) {
      // Iterating for all digits from
      // 1 to 9
      for (int digit = 1; digit <= 9; digit++) {
        // Choosing this as
        // current digit
        ans = (ans + recur(i + 1, digit, N)) % MOD;
      }
    }
    else {
      // Choosing for other positions apart
      // from first
      // Iterating for all digits
      // from 1 to 9
      for (int digit = 1; digit <= 9; digit++) {
        // Choosing this as current
        // digit if it is divisible by
        // previous digit
        if (digit % j == 0) {
          ans = (ans + recur(i + 1, digit, N))
            % MOD;
        }
      }
    }
 
    // Save and return dp value
    return dp[i][j] = ans;
  }
 
  // Function to find number of N digits
  // such that its every digit divisible
  // by its previous digit
  static int countWays(int N)
  {
    // Initializing dp array with - 1
    dp = new int[N + 1][10];
    for (int[] row : dp) {
      Arrays.fill(row, -1);
    }
    // Calling recursive function for
    // finding answer
    int ans = recur(0, 0, N);
    // Returning the answer
    return ans;
  }
 
  public static void main(String[] args)
  {
    // Input 1
    int N = 2;
    // Function Call
    System.out.println(countWays(N));
    // Input 2
    int N1 = 3;
    // Function Call
    System.out.println(countWays(N1));
  }
}
 
// This code is contributed by lokesh.


Python3




MOD = 1e9 + 7
 
# DP table initialized with -1
dp = [[-1 for j in range(10)] for i in range(100001)]
 
# Recursive Function to find number of N
# digits such that its every digit
# divisible by its previous digit
def recur(i, j, N):
 
    # Base case
    if i == N:
        return 1
 
    # If answer for current state is
    # already calculated then just
    # return dp[i][j]
    if dp[i][j] != -1:
        return dp[i][j]
 
    # Answer initialized with zero
    ans = 0
 
    # First element to decide
    if i == 0:
 
        # Iterating for all digits from
        # 1 to 9
        for digit in range(1, 10):
 
            # Choosing this as
            # current digit
            ans = (ans + recur(i + 1, digit, N)) % MOD
    # Choosing for other positions apart
    # from first
    else:
 
        # Iterating for all digits
        # from 1 to 9
        for digit in range(1, 10):
 
            # Choosing this as current
            # digit if it is divisible by
            # previous digit
            if digit % j == 0:
                ans = (ans + recur(i + 1, digit, N)) % MOD
 
    # Save and return dp value
    dp[i][j] = ans
    return ans
 
# Function to find number of N digits
# such that its every digit divisible
# by its previous digit
def count_ways(N):
 
    # Calling recursive function for
    # finding answer
    ans = recur(0, 0, N)
 
    # Returning the answer
    return ans
 
# Driver Code
 
# Input 1
N = 2
 
# Function Call
print(count_ways(N))
 
# Input 2
N1 = 3
dp = [[-1 for j in range(10)] for i in range(100001)]
 
# Function Call
print(count_ways(N1))
 
# This code is contributed by lokeshpotta20.


C#




// C# code to implement the approach
 
using System;
 
public class GFG {
 
  static readonly int MOD = (int)1e9 + 7;
  static int[, ] dp;
 
  // Recursive Function to find number of N
  // digits such that its every digit
  // divisible by its previous digit
  static int recur(int i, int j, int N)
  {
    // Base case
    if (i == N) {
      return 1;
    }
    // If answer for current state is
    // already calculated then just
    // return dp[i][j]
    if (dp[i, j] != -1) {
      return dp[i, j];
    }
    // Answer initialized with zero
    int ans = 0;
 
    // First element to decide
    if (i == 0) {
      // Iterating for all digits from
      // 1 to 9
      for (int digit = 1; digit <= 9; digit++) {
        // Choosing this as
        // current digit
        ans = (ans + recur(i + 1, digit, N)) % MOD;
      }
    }
    else {
      // Choosing for other positions apart
      // from first
      // Iterating for all digits
      // from 1 to 9
      for (int digit = 1; digit <= 9; digit++) {
        // Choosing this as current
        // digit if it is divisible by
        // previous digit
        if (digit % j == 0) {
          ans = (ans + recur(i + 1, digit, N))
            % MOD;
        }
      }
    }
 
    // Save and return dp value
    return dp[i, j] = ans;
  }
 
  // Function to find number of N digits
  // such that its every digit divisible
  // by its previous digit
  static int countWays(int N)
  {
    // Initializing dp array with - 1
    dp = new int[N + 1, 10];
    for (int i = 0; i <= N; i++) {
      for (int j = 0; j <= 9; j++) {
        dp[i, j] = -1;
      }
    }
    // Calling recursive function for
    // finding answer
    int ans = recur(0, 0, N);
    // Returning the answer
    return ans;
  }
 
  static public void Main()
  {
 
    // Input 1
    int N = 2;
    // Function Call
    Console.WriteLine(countWays(N));
    // Input 2
    int N1 = 3;
    // Function Call
    Console.WriteLine(countWays(N1));
  }
}
 
// This code is contributed by lokeshmvs21.


Javascript




// Javascript code to implement the approach
const MOD = 1e9 + 7;
 
// DP table initialized with -1
let dp=new Array(1000001);
for(let i = 0; i < 1000001; i++)
    dp[i] = new Array(10).fill(-1);
 
// Recursive Function to find number of N
// digits such that its every digit
// divisible by its previous digit
function recur( i,  j,  N)
{
 
    // Base case
    if (i == N) {
        return 1;
    }
 
    // If answer for current state is
    // already calculated then just
    // return dp[i][j]
    if (dp[i][j] != -1)
        return dp[i][j];
 
    // Answer initialized with zero
    let ans = 0;
 
    // First element to decide
    if (i == 0) {
 
        // Iterating for all digits from
        // 1 to 9
        for (let digit = 1; digit <= 9; digit++) {
 
            // Choosing this as
            // current digit
            ans = (ans + recur(i + 1, digit, N)) % MOD;
        }
    }
 
    // Choosing for other positions apart
    // from first
    else {
 
        // Iterating for all digits
        // from 1 to 9
        for (let digit = 1; digit <= 9; digit++) {
 
            // Choosing this as current
            // digit if it is divisible by
            // previous digit
            if (digit % j == 0)
                ans = (ans + recur(i + 1, digit, N)) % MOD;
        }
    }
 
    // Save and return dp value
    return dp[i][j] = ans;
}
 
// Function to find number of N digits
// such that its every digit divisible
// by its previous digit
function countWays( N)
{
 
    // Initializing dp array with - 1
    for(let i = 0; i < 100001; i++)
    {
        for(let j = 0; j < 10; j++)
            dp[i][j]=-1;
    }
     
    // Calling recursive function for
    // finding answer
    let ans = recur(0, 0, N);
 
    // Returning the answer
    return ans;
}
 
// Driver Code
// Input 1
let N = 2;
 
// Function Call
console.log(countWays(N));
 
// Input 2
let N1 = 3;
 
// Function Call
console.log(countWays(N1));
 
// This code is contributed by poojaagarwal2.


Output

23
44

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 for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
const int MOD = 1e9 + 7;
 
// Function to find number of N digits
// such that its every digit divisible
// by its previous digit
int countWays(int N)
{
    // DP table to store the number of
    // ways for each subproblem
    vector<vector<int>> dp(N+1, vector<int>(10, 0));
 
    // Base case
    for (int j = 1; j <= 9; j++) {
        dp[1][j] = 1;
    }
 
    // Fill the DP table
    for (int i = 2; i <= N; i++) {
        for (int j = 1; j <= 9; j++) {
            for (int k = j; k <= 9; k++) {
                if (k % j == 0) {
                    dp[i][j] = (dp[i][j] + dp[i-1][k]) % MOD;
                }
            }
        }
    }
 
    // Compute the final answer
    int ans = 0;
    for (int j = 1; j <= 9; j++) {
        ans = (ans + dp[N][j]) % MOD;
    }
 
    // Return the answer
    return ans;
}
 
// Driver Code
int main()
{
    // Input 1
    int N = 2;
 
    // Function Call
    cout << countWays(N) << endl;
 
    // Input 2
    int N1 = 3;
 
    // Function Call
    cout << countWays(N1) << endl;
 
    return 0;
}
 
// this code is contributed by bhardwajji


Java




/*package whatever //do not write package name here */
 
// Java program for the above approach
import java.util.*;
 
class GFG {
 
    static final int MOD = (int) 1e9 + 7;
 
    // Function to find number of N digits
    // such that its every digit divisible
    // by its previous digit
    static int countWays(int N) {
        // DP table to store the number of
        // ways for each subproblem
        int[][] dp = new int[N + 1][10];
 
        // Base case
        for (int j = 1; j <= 9; j++) {
            dp[1][j] = 1;
        }
 
        // Fill the DP table
        for (int i = 2; i <= N; i++) {
            for (int j = 1; j <= 9; j++) {
                for (int k = j; k <= 9; k++) {
                    if (k % j == 0) {
                        dp[i][j] = (dp[i][j] + dp[i - 1][k]) % MOD;
                    }
                }
            }
        }
 
        // Compute the final answer
        int ans = 0;
        for (int j = 1; j <= 9; j++) {
            ans = (ans + dp[N][j]) % MOD;
        }
 
        // Return the answer
        return ans;
    }
 
    // Driver Code
    public static void main (String[] args) {
        // Input 1
        int N = 2;
 
        // Function Call
        System.out.println(countWays(N));
 
        // Input 2
        int N1 = 3;
 
        // Function Call
        System.out.println(countWays(N1));
    }
}
// akashish__


Python3




MOD = int(1e9 + 7)
 
# Function to find number of N digits
# such that its every digit divisible
# by its previous digit
def countWays(N: int) -> int:
    # DP table to store the number of
    # ways for each subproblem
    dp = [[0] * 10 for _ in range(N+1)]
 
    # Base case
    for j in range(1, 10):
        dp[1][j] = 1
 
    # Fill the DP table
    for i in range(2, N+1):
        for j in range(1, 10):
            for k in range(j, 10):
                if k % j == 0:
                    dp[i][j] = (dp[i][j] + dp[i-1][k]) % MOD
 
    # Compute the final answer
    ans = 0
    for j in range(1, 10):
        ans = (ans + dp[N][j]) % MOD
 
    # Return the answer
    return ans
 
# Driver Code
if __name__ == '__main__':
    # Input 1
    N = 2
 
    # Function Call
    print(countWays(N))
 
    # Input 2
    N1 = 3
 
    # Function Call
    print(countWays(N1))


Javascript




const MOD = 1e9 + 7;
 
// Function to find number of N digits
// such that its every digit divisible
// by its previous digit
function countWays(N) {
    // DP table to store the number of
    // ways for each subproblem
    let dp = new Array(N + 1);
    for (let i = 0; i <= N; i++) {
        dp[i] = new Array(10).fill(0);
    }
 
    // Base case
    for (let j = 1; j <= 9; j++) {
        dp[1][j] = 1;
    }
 
    // Fill the DP table
    for (let i = 2; i <= N; i++) {
        for (let j = 1; j <= 9; j++) {
            for (let k = j; k <= 9; k++) {
                if (k % j === 0) {
                    dp[i][j] = (dp[i][j] + dp[i-1][k]) % MOD;
                }
            }
        }
    }
 
    // Compute the final answer
    let ans = 0;
    for (let j = 1; j <= 9; j++) {
        ans = (ans + dp[N][j]) % MOD;
    }
 
    // Return the answer
    return ans;
}
 
// Driver Code
let N = 2;
 
// Function Call
console.log(countWays(N));
 
let N1 = 3;
 
// Function Call
console.log(countWays(N1));


C#




using System;
using System.Collections.Generic;
 
class GFG {
    const int MOD = 1000000007;
 
    // Function to find number of N digits
    // such that its every digit divisible
    // by its previous digit
    static int countWays(int N)
    {
        // DP table to store the number of
        // ways for each subproblem
        List<List<int> > dp = new List<List<int> >();
        for (int i = 0; i <= N; i++) {
            dp.Add(new List<int>());
            for (int j = 0; j < 10; j++) {
                dp[i].Add(0);
            }
        }
 
        // Base case
        for (int j = 1; j <= 9; j++) {
            dp[1][j] = 1;
        }
 
        // Fill the DP table
        for (int i = 2; i <= N; i++) {
            for (int j = 1; j <= 9; j++) {
                for (int k = j; k <= 9; k++) {
                    if (k % j == 0) {
                        dp[i][j] = (dp[i][j] + dp[i - 1][k])
                                   % MOD;
                    }
                }
            }
        }
 
        // Compute the final answer
        int ans = 0;
        for (int j = 1; j <= 9; j++) {
            ans = (ans + dp[N][j]) % MOD;
        }
 
        // Return the answer
        return ans;
    }
 
    // Driver Code
    static void Main()
    {
        // Input 1
        int N = 2;
 
        // Function Call
        Console.WriteLine(countWays(N));
 
        // Input 2
        int N1 = 3;
 
        // Function Call
        Console.WriteLine(countWays(N1));
    }
}


Output

23
44

Time Complexity : O(N) 

Auxiliary Space: O(N)

Related Articles:



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads