Given three integers, N, K and M. The task is to find out the number of binary strings of length N which always starts with 1, in which there can be at most M consecutive 1’s or 0’s and they alternate exactly K times.
Examples:
Input: N = 5, K = 3, M = 2
Output: 3
The 3 configurations are:
11001
10011
11011
Explanation:
Notice that the groups of 1’s and 0’s alternate exactly K timesInput: N = 7, K = 4, M = 3
Output: 16
Approach: Since this problem involves both overlapping sub-problem and optimal substructure. So, this problem can be solved using dynamic programming.
-
Sub-problem: DP[i][j] represents the number of binary strings upto length i having j alternating groups till now. So, to calculate dp[N][K] if we know the value of dp[n-j][k-1], then we can easily get the result by summing up the sub-problem value over j = 1 to m (DP[N][K] represents the final answer).
As shown below in the recursion tree diagram, it is observed many sub-problem overlaps. So, the result needs to be cached to avoid redundant calculations.
-
Optimal substructure:
-
By following the top-down DP approach:
As we can have a group which can be atmost of the length M, so we iterate on every possible length and recur with new N and decreasing K by 1, as a new group is formed. Solution to sub-problem is cached and summed up to give final result dp[N][K]. -
Base Case:
- When N is 0 and K is 0, then return 1
- When N is 0 but K is not 0, then return 0
- When N is not 0 but K is 0, then return 0
- When both are negative, return 0
Below is the implementation of above approach:
// C++ program to find the count // of Binary strings of length N // having atmost M consecutive 1s or 0s // alternatively exactly K times #include <bits/stdc++.h> using namespace std;
// Array to contain the final result int dp[1000][1000];
// Function to get the number // of desirable binary strings int solve( int n, int k, int m)
{ // if we reach end of string
// and groups are exhausted,
// return 1
if (n == 0 && k == 0)
return 1;
// if length is exhausted but
// groups are still to be made,
// return 0
if (n == 0 && k != 0)
return 0;
// if length is not exhausted
// but groups are exhausted,
// return 0
if (n != 0 && k == 0)
return 0;
// if both are negative
// just return 0
if (n < 0 || k < 0)
return 0;
// if already calculated,
// return it
if (dp[n][k])
return dp[n][k];
// initialise answer
// for each state
int ans = 0;
// loop through every
// possible m
for ( int j = 1; j <= m; j++) {
ans += solve(n - j, k - 1, m);
}
return dp[n][k] = ans;
} // Driver code int main()
{ int N = 7, K = 4, M = 3;
cout << solve(N, K, M);
} |
// Java program to find the count of // Binary Strings of length N having // atmost M consecutive 1s or 0s // alternatively exactly K times import java.util.*;
class GFG{
// Array to contain the final result static int [][]dp = new int [ 1000 ][ 1000 ];
// Function to get the number // of desirable binary strings static int solve( int n, int k, int m)
{ // If we reach end of string
// and groups are exhausted,
// return 1
if (n == 0 && k == 0 )
return 1 ;
// If length is exhausted but
// groups are still to be made,
// return 0
if (n == 0 && k != 0 )
return 0 ;
// If length is not exhausted
// but groups are exhausted,
// return 0
if (n != 0 && k == 0 )
return 0 ;
// If both are negative
// just return 0
if (n < 0 || k < 0 )
return 0 ;
// If already calculated,
// return it
if (dp[n][k] > 0 )
return dp[n][k];
// Initialise answer
// for each state
int ans = 0 ;
// Loop through every
// possible m
for ( int j = 1 ; j <= m; j++)
{
ans += solve(n - j, k - 1 , m);
}
return dp[n][k] = ans;
} // Driver code public static void main(String[] args)
{ int N = 7 , K = 4 , M = 3 ;
System.out.print(solve(N, K, M));
} } // This code is contributed by Rajput-Ji |
# Python3 program to find the count # of Binary strings of length N # having atmost M consecutive 1s or # 0s alternatively exactly K times # List to contain the final result rows, cols = ( 1000 , 1000 )
dp = [[ 0 for i in range (cols)]
for j in range (rows)]
# Function to get the number # of desirable binary strings def solve(n, k, m):
# If we reach end of string
# and groups are exhausted,
# return 1
if n = = 0 and k = = 0 :
return 1
# If length is exhausted but
# groups are still to be made,
# return 0
if n = = 0 and k ! = 0 :
return 0
# If length is not exhausted
# but groups are exhausted,
# return 0
if n ! = 0 and k = = 0 :
return 0
# If both are negative
# just return 0
if n < 0 or k < 0 :
return 0
# If already calculated,
# return it
if dp[n][k]:
return dp[n][k]
# Initialise answer
# for each state
ans = 0
# Loop through every
# possible m
for j in range ( 1 , m + 1 ):
ans = ans + solve(n - j,
k - 1 , m)
dp[n][k] = ans
return dp[n][k]
# Driver code N = 7
K = 4
M = 3
print (solve(N, K, M))
# This code is contributed by ishayadav181 |
// C# program to find the count of // binary strings of length N having // atmost M consecutive 1s or 0s // alternatively exactly K times using System;
class GFG{
// Array to contain the readonly result static int [,]dp = new int [1000, 1000];
// Function to get the number // of desirable binary strings static int solve( int n, int k, int m)
{ // If we reach end of string
// and groups are exhausted,
// return 1
if (n == 0 && k == 0)
return 1;
// If length is exhausted but
// groups are still to be made,
// return 0
if (n == 0 && k != 0)
return 0;
// If length is not exhausted
// but groups are exhausted,
// return 0
if (n != 0 && k == 0)
return 0;
// If both are negative
// just return 0
if (n < 0 || k < 0)
return 0;
// If already calculated,
// return it
if (dp[n, k] > 0)
return dp[n, k];
// Initialise answer
// for each state
int ans = 0;
// Loop through every
// possible m
for ( int j = 1; j <= m; j++)
{
ans += solve(n - j, k - 1, m);
}
return dp[n, k] = ans;
} // Driver code public static void Main(String[] args)
{ int N = 7, K = 4, M = 3;
Console.Write(solve(N, K, M));
} } // This code is contributed by gauravrajput1 |
16
Time complexity: O(N*K*M)
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.