Open In App

Count of numbers upto N digits formed using digits 0 to K-1 without any adjacent 0s

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Given two integers N and K, the task is to count the numbers up to N digits such that no two zeros are adjacents and the range of digits are from 0 to K-1.
Examples: 

Input: N = 2, K = 3 
Output:
Explanation: 
There are 8 such numbers such that digits are from 0 to 2 only, without any adjacent 0s: {1, 2, 10, 11, 12, 20, 21, 22}

Input: N = 3, K = 3 
Output: 22 

Approach: The idea is to use Dynamic Programming to solve this problem. 
Let DP[i][j] be the number of desirable numbers up to ith digit of the number, and its last digit as j.
Observations:

  • The number of ways to fill a place is(K-1)
  • As we know, zero’s can’t be adjacent. So when our last element is 0, means the previous index is filled by 1 way, that is 0. Therefore, current place can only be filled by (K-1) digits.
  • If the last place is filled by (K-1) digits, Then current digit place can be filled by either 0 or (K-1) digits.


Base Case:

  • If n == 1 and last == K, then we can fill this place by (K-1) digits, return (K-1)
  • Else, return 1


Recurrence relation:

When last digit place is not filled by zero then 

dp[i][j] = (K-1)*solve(n-1, K) + (K-1)*solve(n-1, 1)
 
When Last digit place is filled by zero then 
 
dp[i][j] = solve(n-1, K)                 


Below is the implementation of above approach:

C++

// C++ implementation to count the
// numbers upto N digits such that
// no two zeros are adjacent
 
#include <bits/stdc++.h>
using namespace std;
 
int dp[15][10];
 
// Function to count the
// numbers upto N digits such that
// no two zeros are adjacent
int solve(int n, int last, int k)
{
    // Condition to check if only
    // one element remains
    if (n == 1) {
 
        // If last element is non
        // zero, return K-1
        if (last == k) {
            return (k - 1);
        }
        // If last element is 0
        else {
            return 1;
        }
    }
 
    // Condition to check if value
    // calculated already
    if (dp[n][last])
        return dp[n][last];
 
    // If last element is non zero,
    // then two cases arise,
    // current element can be either
    // zero or non zero
    if (last == k) {
 
        // Memoize this case
        return dp[n][last]
               = (k - 1)
                     * solve(n - 1, k, k)
                 + (k - 1)
                       * solve(n - 1, 1, k);
    }
 
    // If last is 0, then current
    // can only be non zero
    else {
 
        // Memoize and return
        return dp[n][last]
               = solve(n - 1, k, k);
    }
}
 
// Driver Code
int main()
{
    // Given N and K
    int n = 2, k = 3;
 
    // Function Call
    int x = solve(n, k, k)
            + solve(n, 1, k);
    cout << x;
}

                    

Java

// Java implementation to count the
// numbers upto N digits such that
// no two zeros are adjacent
import java.io.*;
public class GFG{
     
static int[][] dp = new int[15][10];
 
// Function to count the numbers
// upto N digits such that
// no two zeros are adjacent
static int solve(int n, int last, int k)
{
     
    // Condition to check if only
    // one element remains
    if (n == 1)
    {
         
        // If last element is non
        // zero, return K-1
        if (last == k)
        {
            return (k - 1);
        }
         
        // If last element is 0
        else
        {
            return 1;
        }
    }
 
    // Condition to check if
    // value calculated already
    if (dp[n][last] == 1)
        return dp[n][last];
 
    // If last element is non zero,
    // then two cases arise, current
    // element can be either zero
    // or non zero
    if (last == k)
    {
         
        // Memoize this case
        return dp[n][last] = (k - 1) *
                        solve(n - 1, k, k) +
                             (k - 1) *
                        solve(n - 1, 1, k);
    }
     
    // If last is 0, then current
    // can only be non zero
    else
    {
 
        // Memoize and return
        return dp[n][last] = solve(n - 1, k, k);
    }
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given N and K
    int n = 2, k = 3;
 
    // Function Call
    int x = solve(n, k, k) +
            solve(n, 1, k);
     
    System.out.print(x);
}
}
 
// This code is contributed by Ritik Bansal

                    

Python3

# Python3 implementation to count the
# numbers upto N digits such that
# no two zeros are adjacent
dp = [[0] * 10 for j in range(15)]
 
# Function to count the numbers
# upto N digits such that no two
# zeros are adjacent
def solve(n, last, k):
 
    # Condition to check if only
    # one element remains
    if (n == 1):
 
        # If last element is non
        # zero, return K-1
        if (last == k):
            return (k - 1)
         
        # If last element is 0
        else:
            return 1
 
    # Condition to check if value
    # calculated already
    if (dp[n][last]):
        return dp[n][last]
 
    # If last element is non zero,
    # then two cases arise, current
    # element can be either zero or
    # non zero
    if (last == k):
 
        # Memoize this case
        dp[n][last] = ((k - 1) *
                  solve(n - 1, k, k) +
                       (k - 1) *
                  solve(n - 1, 1, k))
                        
        return dp[n][last]
 
    # If last is 0, then current
    # can only be non zero
    else:
 
        # Memoize and return
        dp[n][last] = solve(n - 1, k, k)
        return dp[n][last]
 
# Driver code
 
# Given N and K
n = 2
k = 3
 
# Function call
x = solve(n, k, k) + solve(n, 1, k)
 
print(x)
 
# This code is contributed by himanshu77

                    

C#

// C# implementation to count the
// numbers upto N digits such that
// no two zeros are adjacent
using System;
 
class GFG{
     
public static int [,]dp = new int[15, 10];
 
// Function to count the numbers
// upto N digits such that
// no two zeros are adjacent
public static int solve(int n, int last, int k)
{
     
    // Condition to check if only
    // one element remains
    if (n == 1)
    {
         
        // If last element is non
        // zero, return K-1
        if (last == k)
        {
            return (k - 1);
        }
         
        // If last element is 0
        else
        {
            return 1;
        }
    }
 
    // Condition to check if
    // value calculated already
    if (dp[n, last] == 1)
        return dp[n, last];
 
    // If last element is non zero,
    // then two cases arise, current
    // element can be either zero
    // or non zero
    if (last == k)
    {
         
        // Memoize this case
        return dp[n, last] = (k - 1) *
                        solve(n - 1, k, k) +
                             (k - 1) *
                        solve(n - 1, 1, k);
    }
     
    // If last is 0, then current
    // can only be non zero
    else
    {
 
        // Memoize and return
        return dp[n, last] = solve(n - 1, k, k);
    }
}
 
// Driver Code
public static void Main(string[] args)
{
     
    // Given N and K
    int n = 2, k = 3;
 
    // Function Call
    int x = solve(n, k, k) +
            solve(n, 1, k);
     
    Console.WriteLine(x);
}
}
 
// This code is contributed by SoumikMondal

                    

Javascript

<script>
 
// Javascript implementation to count the
// numbers upto N digits such that
// no two zeros are adjacent
 
var dp = Array.from(Array(15),
() => Array(10).fill(0));
 
// Function to count the
// numbers upto N digits such that
// no two zeros are adjacent
function solve(n, last, k)
{
    // Condition to check if only
    // one element remains
    if (n == 1) {
 
        // If last element is non
        // zero, return K-1
        if (last == k) {
            return (k - 1);
        }
        // If last element is 0
        else {
            return 1;
        }
    }
 
    // Condition to check if value
    // calculated already
    if ((dp[n][last])!=0)
        return dp[n][last];
 
    // If last element is non zero,
    // then two cases arise,
    // current element can be either
    // zero or non zero
    if (last == k) {
 
        // Memoize this case
        return dp[n][last]
               = (k - 1)
                     * solve(n - 1, k, k)
                 + (k - 1)
                       * solve(n - 1, 1, k);
    }
 
    // If last is 0, then current
    // can only be non zero
    else {
 
        // Memoize and return
        dp[n][last]
               = solve(n - 1, k, k);
        return dp[n][last];
    }
}
 
// Driver Code
// Given N and K
var n = 2, k = 3;
// Function Call
var x = solve(n, k, k)
        + solve(n, 1, k);
document.write(x);
 
 
</script>

                    

Output: 
8

 

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

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

Steps to solve this problem :

  • Create a table DP to store the solution of the subproblems.
  • Initialize the table with base cases 
  • Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP.
  • At last return and print the final solution stored in x , where x = dp[n][k] + dp[n][1] .

Implementation :

C++

// C++ program for above approach
 
#include <bits/stdc++.h>
using namespace std;
 
int dp[15][10];
 
// Function to count the
// numbers upto N digits such that
// no two zeros are adjacent
int solve(int n, int k)
{
    // Initialize the base cases
    for (int i = 1; i <= k; i++) {
        dp[1][i] = (i == k) ? (k - 1) : 1;
    }
 
    // Fill the table using previously computed values
    for (int i = 2; i <= n; i++) {
        for (int j = 1; j <= k; j++) {
            if (j == k) {
                dp[i][j] = (k - 1) * dp[i - 1][k] + (k - 1) * dp[i - 1][1];
            } else {
                dp[i][j] = dp[i - 1][k];
            }
        }
    }
 
    // Compute the final result
    int x = dp[n][k] + dp[n][1];
    return x;
}
 
// Driver Code
int main()
{
    // Given N and K
    int n = 2, k = 3;
 
    // Function Call
    int x = solve(n, k);
    cout << x;
}
 
// this code contributed by bhardwajji

                    

Java

import java.util.*;
 
public class Main {
    static int dp[][] = new int[15][10];
 
    // Function to count the
    // numbers upto N digits such that
    // no two zeros are adjacent
    static int solve(int n, int k) {
        // Initialize the base cases
        for (int i = 1; i <= k; i++) {
            dp[1][i] = (i == k) ? (k - 1) : 1;
        }
 
        // Fill the table using previously computed values
        for (int i = 2; i <= n; i++) {
            for (int j = 1; j <= k; j++) {
                if (j == k) {
                    dp[i][j] = (k - 1) * dp[i - 1][k] + (k - 1) * dp[i - 1][1];
                } else {
                    dp[i][j] = dp[i - 1][k];
                }
            }
        }
 
        // Compute the final result
        int x = dp[n][k] + dp[n][1];
        return x;
    }
 
    // Driver Code
    public static void main(String[] args) {
        // Given N and K
        int n = 2, k = 3;
 
        // Function Call
        int x = solve(n, k);
        System.out.println(x);
    }
}

                    

Python3

# Python program for above approach
 
# Function to count the
# numbers upto N digits such that
# no two zeros are adjacent
def solve(n, k):
    dp = [[0 for i in range(10)] for j in range(15)]
 
    # Initialize the base cases
    for i in range(1, k + 1):
        dp[1][i] = k - 1 if i == k else 1
 
    # Fill the table using previously computed values
    for i in range(2, n + 1):
        for j in range(1, k + 1):
            if j == k:
                dp[i][j] = (k - 1) * dp[i - 1][k] + (k - 1) * dp[i - 1][1]
            else:
                dp[i][j] = dp[i - 1][k]
 
    # Compute the final result
    x = dp[n][k] + dp[n][1]
    return x
 
# Driver Code
if __name__ == "__main__":
    # Given N and K
    n = 2
    k = 3
 
    # Function Call
    x = solve(n, k)
    print(x)

                    

Javascript

// JavaScript program for above approach
 
let dp = Array.from({length: 15}, () => Array.from({length: 10}).fill(0));
 
// Function to count the
// numbers upto N digits such that
// no two zeros are adjacent
function solve(n, k)
{
// Initialize the base cases
for (let i = 1; i <= k; i++) {
dp[1][i] = (i == k) ? (k - 1) : 1;
}
// Fill the table using previously computed values
for (let i = 2; i <= n; i++) {
    for (let j = 1; j <= k; j++) {
        if (j == k) {
            dp[i][j] = (k - 1) * dp[i - 1][k] + (k - 1) * dp[i - 1][1];
        } else {
            dp[i][j] = dp[i - 1][k];
        }
    }
}
 
// Compute the final result
let x = dp[n][k] + dp[n][1];
return x;
}
 
// Driver Code
let n = 3, k = 3;
 
// Function Call
let x = solve(n, k);
console.log(x);

                    

C#

// C# program for above approach
 
using System;
 
class Program
{
static int[,] dp = new int[15, 10];
  // Function to count the
// numbers upto N digits such that
// no two zeros are adjacent
static int Solve(int n, int k)
{
    // Initialize the base cases
    for (int i = 1; i <= k; i++) {
        dp[1, i] = (i == k) ? (k - 1) : 1;
    }
 
    // Fill the table using previously computed values
    for (int i = 2; i <= n; i++) {
        for (int j = 1; j <= k; j++) {
            if (j == k) {
                dp[i, j] = (k - 1) * dp[i - 1, k] + (k - 1) * dp[i - 1, 1];
            } else {
                dp[i, j] = dp[i - 1, k];
            }
        }
    }
 
    // Compute the final result
    int x = dp[n, k] + dp[n, 1];
    return x;
}
 
// Driver Code
static void Main(string[] args)
{
    // Given N and K
    int n = 2, k = 3;
 
    // Function Call
    int x = Solve(n, k);
    Console.WriteLine(x);
}
}

                    

Output
8

Time Complexity: O(N*K) 
Auxiliary Space: O(N*10)



Last Updated : 03 May, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads