📌  相关文章
📜  长度为N的二进制字符串的计数,最多具有M个连续的1或0,或者正好是K次(1)

📅  最后修改于: 2023-12-03 15:28:36.112000             🧑  作者: Mango

Length N Binary String Count with At Most M Consecutive 1's or 0's, or Exactly K Times

Introduction

As a programmer, you may come across the problem of counting the number of binary strings of length N that have at most M consecutive 1's or 0's, or exactly K times. In this article, we will discuss the techniques and algorithms that can be used to solve this problem efficiently.

Problem Definition

Given a positive integer N, a non-negative integer M, and a non-negative integer K, count the number of binary strings of length N that have at most M consecutive 1's or 0's, or exactly K times.

Approach

Method #1: Dynamic Programming

We can use dynamic programming to solve this problem. Let's define two arrays: dp0 and dp1.

  • dp0[i] stores the number of binary strings of length i that have at most M consecutive 0's.
  • dp1[i] stores the number of binary strings of length i that have at most M consecutive 1's.

Now, let's define the base cases:

  • dp0[0] = 1
  • dp1[0] = 1
  • dp0[1] = 2
  • dp1[1] = 2

Next, we can use the following recurrence relation to fill out the remaining cells:

  • dp0[i] = dp0[i-1] + dp0[i-2] + ... + dp0[i-M]
  • dp1[i] = dp1[i-1] + dp1[i-2] + ... + dp1[i-M]

The final answer will be dp0[N] + dp1[N] - (if K == 0 then 0 else dp0[N-K] + dp1[N-K]).

Here's the Python code snippet for this approach:

def count_binary_strings(N, M, K):
    dp0 = [0] * (N + 1)
    dp1 = [0] * (N + 1)
    dp0[0], dp1[0] = 1, 1
    dp0[1], dp1[1] = 2, 2
    
    for i in range(2, N+1):
        dp0[i] = dp0[i-1] + dp0[i-2] + sum(dp0[max(0, i-M-1):i-1])
        dp1[i] = dp1[i-1] + dp1[i-2] + sum(dp1[max(0, i-M-1):i-1])

    return dp0[N] + dp1[N] - (0 if K == 0 else dp0[N-K] + dp1[N-K])

Method #2: Combinatorial Methods

We can also use combinatorial methods to solve this problem. Let's define f(n, m) to be the number of binary strings of length n that have at most m consecutive 1's. Similarly, let's define g(n, m) to be the number of binary strings of length n that have at most m consecutive 0's.

Using these definitions, we can derive the following recurrence relations:

  • f(n, m) = f(n-1, m) + f(n-2, m) + ... + f(n-m, m)
  • g(n, m) = g(n-1, m) + g(n-2, m) + ... + g(n-m, m)

Next, let's define h(n, m) to be the number of binary strings of length n that have exactly m consecutive 1's. Using this definition, we can derive the following recurrence relation:

  • h(n, m) = f(n-m-1, m-1) + f(n-m-2, m-1) + ... + f(0, m-1)

Using these recurrences, we can compute the answer in O(NM) time.

Here's the Python code snippet for this approach:

def ncr(n,r):
    f = math.factorial
    return f(n) // f(r) // f(n-r)

def count_binary_strings(N, M, K):
    f, g = [0]*(N+1), [0]*(N+1)
    h = [[0]*(K+1) for _ in range(N+1)]

    f[0], f[1] = 1, 2
    g[0], g[1] = 1, 2

    for i in range(2, N+1):
        f[i] = f[i-1] + f[i-2] + sum([f[j] for j in range(max(0, i-M-1), i-1)])
        g[i] = g[i-1] + g[i-2] + sum([g[j] for j in range(max(0, i-M-1), i-1)])

    for i in range(K+1):
        for j in range(i, N+1):
            if i == 0:
                h[j][i] = 1
            else:
                h[j][i] = sum([f[k] * ncr(j-k-i, i-1) for k in range(j-i)])

    return f[N] + g[N] - (0 if K == 0 else sum([h[N-k][K] for k in range(K, N+1)]))
Conclusion

In this article, we discussed two approaches to count the number of binary strings of length N that have at most M consecutive 1's or 0's, or exactly K times. Both the dynamic programming and combinatorial methods have a time complexity of O(NM), but the combinatorial method is slightly faster.