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++ 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 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.
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# 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 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++ 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
/*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__
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))
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));
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: