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. |
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)); } } |
23 44
Time Complexity : O(N)
Auxiliary Space: O(N)
Related Articles:
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!