📌  相关文章
📜  长度为 N 的二进制字符串的计数,偶数设置位计数,最多 K 个连续 1(1)

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

长度为 N 的二进制字符串的计数

问题描述

给定二进制字符串长度 N 和整数 K,计算由长度为 N 的二进制字符串组成的集合中,满足偶数位数值的二进制位为 1,且最多有 K 个连续 1 的字符串的数量。

思路

对于长度为 N 的二进制字符串,可以利用动态规划的方法求解。具体地,设 $f_{i, j, k}$ 表示二进制字符串的前 $i$ 位中,偶数位数值为 1 的二进制位数量为 $j$,最近的连续 1 的长度为 $k$ 的二进制字符串数量。其中,$0 \leq j \leq \lfloor i/2 \rfloor$,$0 \leq k \leq K$。

则有以下递推式:

$$ f_{i, j, 0} = \sum_{j'=j}^{\lfloor i/2 \rfloor} f_{i-1, j', 1} $$

$$ f_{i, j, k} = f_{i-1, j, k-1} + f_{i-1, j, 0} \quad (k > 0) $$

根据递推式,可以得到最终的结果:

$$ \sum_{j=0}^{\lfloor N/2 \rfloor} f_{N, j, 0} $$

其中,初始条件为 $f_{0, 0, 0} = 1$。

代码实现
def count_binary_strings(N: int, K: int) -> int:
    dp = [[[0] * (K+1) for _ in range(N//2+1)] for _ in range(N+1)]
    dp[0][0][0] = 1
    for i in range(1, N+1):
        for j in range(N//2+1):
            for k in range(K+1):
                dp[i][j][0] = sum(dp[i-1][j2][1] for j2 in range(j, N//2+1))
                if k > 0:
                    dp[i][j][k] = dp[i-1][j][k-1] + dp[i-1][j][0]
                else:
                    dp[i][j][k] = dp[i][j][0]
    return sum(dp[N][j][0] for j in range(N//2+1))

具体的实现与如上所述的递推式完全对应。时间复杂度为 $O(N^2 K)$,空间复杂度为 $O(N K)$,可以通过本题。