Count of numbers upto N digits formed using digits 0 to K-1 without any adjacent 0s
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: 8
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
- 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
When Last digit place is filled by zero then
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int dp[15][10];
int solve( int n, int last, int k)
{
if (n == 1) {
if (last == k) {
return (k - 1);
}
else {
return 1;
}
}
if (dp[n][last])
return dp[n][last];
if (last == k) {
return dp[n][last]
= (k - 1)
* solve(n - 1, k, k)
+ (k - 1)
* solve(n - 1, 1, k);
}
else {
return dp[n][last]
= solve(n - 1, k, k);
}
}
int main()
{
int n = 2, k = 3;
int x = solve(n, k, k)
+ solve(n, 1, k);
cout << x;
}
|
Java
import java.io.*;
public class GFG{
static int [][] dp = new int [ 15 ][ 10 ];
static int solve( int n, int last, int k)
{
if (n == 1 )
{
if (last == k)
{
return (k - 1 );
}
else
{
return 1 ;
}
}
if (dp[n][last] == 1 )
return dp[n][last];
if (last == k)
{
return dp[n][last] = (k - 1 ) *
solve(n - 1 , k, k) +
(k - 1 ) *
solve(n - 1 , 1 , k);
}
else
{
return dp[n][last] = solve(n - 1 , k, k);
}
}
public static void main(String[] args)
{
int n = 2 , k = 3 ;
int x = solve(n, k, k) +
solve(n, 1 , k);
System.out.print(x);
}
}
|
Python3
dp = [[ 0 ] * 10 for j in range ( 15 )]
def solve(n, last, k):
if (n = = 1 ):
if (last = = k):
return (k - 1 )
else :
return 1
if (dp[n][last]):
return dp[n][last]
if (last = = k):
dp[n][last] = ((k - 1 ) *
solve(n - 1 , k, k) +
(k - 1 ) *
solve(n - 1 , 1 , k))
return dp[n][last]
else :
dp[n][last] = solve(n - 1 , k, k)
return dp[n][last]
n = 2
k = 3
x = solve(n, k, k) + solve(n, 1 , k)
print (x)
|
C#
using System;
class GFG{
public static int [,]dp = new int [15, 10];
public static int solve( int n, int last, int k)
{
if (n == 1)
{
if (last == k)
{
return (k - 1);
}
else
{
return 1;
}
}
if (dp[n, last] == 1)
return dp[n, last];
if (last == k)
{
return dp[n, last] = (k - 1) *
solve(n - 1, k, k) +
(k - 1) *
solve(n - 1, 1, k);
}
else
{
return dp[n, last] = solve(n - 1, k, k);
}
}
public static void Main( string [] args)
{
int n = 2, k = 3;
int x = solve(n, k, k) +
solve(n, 1, k);
Console.WriteLine(x);
}
}
|
Javascript
<script>
var dp = Array.from(Array(15),
() => Array(10).fill(0));
function solve(n, last, k)
{
if (n == 1) {
if (last == k) {
return (k - 1);
}
else {
return 1;
}
}
if ((dp[n][last])!=0)
return dp[n][last];
if (last == k) {
return dp[n][last]
= (k - 1)
* solve(n - 1, k, k)
+ (k - 1)
* solve(n - 1, 1, k);
}
else {
dp[n][last]
= solve(n - 1, k, k);
return dp[n][last];
}
}
var n = 2, k = 3;
var x = solve(n, k, k)
+ solve(n, 1, k);
document.write(x);
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
int dp[15][10];
int solve( int n, int k)
{
for ( int i = 1; i <= k; i++) {
dp[1][i] = (i == k) ? (k - 1) : 1;
}
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];
}
}
}
int x = dp[n][k] + dp[n][1];
return x;
}
int main()
{
int n = 2, k = 3;
int x = solve(n, k);
cout << x;
}
|
Java
import java.util.*;
public class Main {
static int dp[][] = new int [ 15 ][ 10 ];
static int solve( int n, int k) {
for ( int i = 1 ; i <= k; i++) {
dp[ 1 ][i] = (i == k) ? (k - 1 ) : 1 ;
}
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];
}
}
}
int x = dp[n][k] + dp[n][ 1 ];
return x;
}
public static void main(String[] args) {
int n = 2 , k = 3 ;
int x = solve(n, k);
System.out.println(x);
}
}
|
Python3
def solve(n, k):
dp = [[ 0 for i in range ( 10 )] for j in range ( 15 )]
for i in range ( 1 , k + 1 ):
dp[ 1 ][i] = k - 1 if i = = k else 1
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]
x = dp[n][k] + dp[n][ 1 ]
return x
if __name__ = = "__main__" :
n = 2
k = 3
x = solve(n, k)
print (x)
|
Javascript
let dp = Array.from({length: 15}, () => Array.from({length: 10}).fill(0));
function solve(n, k)
{
for (let i = 1; i <= k; i++) {
dp[1][i] = (i == k) ? (k - 1) : 1;
}
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];
}
}
}
let x = dp[n][k] + dp[n][1];
return x;
}
let n = 3, k = 3;
let x = solve(n, k);
console.log(x);
|
C#
using System;
class Program
{
static int [,] dp = new int [15, 10];
static int Solve( int n, int k)
{
for ( int i = 1; i <= k; i++) {
dp[1, i] = (i == k) ? (k - 1) : 1;
}
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];
}
}
}
int x = dp[n, k] + dp[n, 1];
return x;
}
static void Main( string [] args)
{
int n = 2, k = 3;
int x = Solve(n, k);
Console.WriteLine(x);
}
}
|
Time Complexity: O(N*K)
Auxiliary Space: O(N*10)
Last Updated :
03 May, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...