📅  最后修改于: 2023-12-03 15:28:36.112000             🧑  作者: Mango
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.
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.
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])
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)]))
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.