Count of Binary strings of length N having atmost M consecutive 1s or 0s alternatively exactly K times

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 times

Input: 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:
         $dp[i][j]=$$\sum_{j=1}^{M} f(N-j, K-1)

  • 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:
    1. When N is 0 and K is 0, then return 1
    2. When N is 0 but K is not 0, then return 0
    3. When N is not 0 but K is 0, then return 0
    4. When both are negative, return 0

Below is the implementation of above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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);
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Python 3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Output:

16

Time complexity: O(N*K*M)

Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: DSA Self Paced. Become industry ready at a student-friendly price.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.