📌  相关文章
📜  计算相邻两个集合位出现 k 次的二进制字符串

📅  最后修改于: 2021-09-22 09:55:11             🧑  作者: Mango

给定两个整数 n 和 k,计算长度为 n 的二进制字符串的数量,其中 k 作为相邻 1 出现的次数。

例子:

Input  : n = 5, k = 2
Output : 6
Explanation:
Binary strings of length 5 in which k number of times
two adjacent set bits appear.
00111  
01110
11100
11011
10111
11101

Input  : n = 4, k = 1
Output : 3
Explanation:
Binary strings of length 3 in which k number of times
two adjacent set bits appear.
0011  
1100
0110

让我们尝试为上述问题陈述编写递归函数:
1) n = 1,只存在两个长度为1的二进制字符串,没有任何相邻的1
字符串 1:“0”
字符串 2:“1”
2) 对于所有 n > 1 和所有 k,出现两种情况
a) 以 0 结尾的字符串:长度为 n 的字符串可以通过将 0 附加到所有长度为 n-1 的字符串中来创建,这些字符串的 k 次是两个相邻的 1 以 0 和 1 结尾(在第 n 个位置有 0 不会改变计数相邻的 1)。
b) 以 1 结尾的字符串:长度为 n 的字符串可以通过将 1 附加到所有长度为 n-1 且具有 k 次相邻 1 且以 0 结尾的字符串以及所有长度为 n-1 且具有 k-1 个相邻 1 的字符串后附加 1 来创建以 1 结尾

示例:让 s = 011 即以 1 结尾的字符串相邻计数为 1。向其添加 1,s = 0111 增加相邻 1 的计数。

Let there be an array dp[i][j][2] where dp[i][j][0]
denotes number of binary strings with length i having
j number of two adjacent 1's and ending with 0.
Similarly dp[i][j][1] denotes the same binary strings
with length i and j adjacent 1's but ending with 1.
Then: 
    dp[1][0][0] = 1 and dp[1][0][1] = 1
    For all other i and j,
        dp[i][j][0] = dp[i-1][j][0] + dp[i-1][j][1]
        dp[i][j][1] = dp[i-1][j][0] + dp[i-1][j-1][1]

Then, output dp[n][k][0] + dp[n][k][1]
C++
// C++ program to count number of binary strings
// with k times appearing consecutive 1's.
#include 
using namespace std;
 
int countStrings(int n, int k)
{
    // dp[i][j][0] stores count of binary
    // strings of length i with j consecutive
    // 1's and ending at 0.
    // dp[i][j][1] stores count of binary
    // strings of length i with j consecutive
    // 1's and ending at 1.
    int dp[n + 1][k + 1][2];
    memset(dp, 0, sizeof(dp));
 
    // If n = 1 and k = 0.
    dp[1][0][0] = 1;
    dp[1][0][1] = 1;
 
    for (int i = 2; i <= n; i++) {
 
        // number of adjacent 1's can not exceed i-1
        for (int j = 0; j <= k; j++) {
            dp[i][j][0] = dp[i - 1][j][0] + dp[i - 1][j][1];
            dp[i][j][1] = dp[i - 1][j][0];
 
            if (j - 1 >= 0)
                dp[i][j][1] += dp[i - 1][j - 1][1];
        }
    }
 
    return dp[n][k][0] + dp[n][k][1];
}
 
// Driver code
int main()
{
    int n = 5, k = 2;
    cout << countStrings(n, k);
    return 0;
}


Java
// Java program to count number of binary strings
// with k times appearing consecutive 1's.
class GFG {
 
    static int countStrings(int n, int k)
    {
        // dp[i][j][0] stores count of binary
        // strings of length i with j consecutive
        // 1's and ending at 0.
        // dp[i][j][1] stores count of binary
        // strings of length i with j consecutive
        // 1's and ending at 1.
        int dp[][][] = new int[n + 1][k + 1][2];
 
        // If n = 1 and k = 0.
        dp[1][0][0] = 1;
        dp[1][0][1] = 1;
 
        for (int i = 2; i <= n; i++) {
 
            // number of adjacent 1's can not exceed i-1
            for (int j = 0; j < i && j < k + 1; j++) {
                dp[i][j][0] = dp[i - 1][j][0] + dp[i - 1][j][1];
                dp[i][j][1] = dp[i - 1][j][0];
 
                if (j - 1 >= 0) {
                    dp[i][j][1] += dp[i - 1][j - 1][1];
                }
            }
        }
 
        return dp[n][k][0] + dp[n][k][1];
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int n = 5, k = 2;
        System.out.println(countStrings(n, k));
    }
}
 
// This code has been contributed by 29AjayKumar


Python3
# Python3 program to count number of
# binary strings with k times appearing
# consecutive 1's.
def countStrings(n, k):
 
    # dp[i][j][0] stores count of binary
    # strings of length i with j consecutive
    # 1's and ending at 0.
    # dp[i][j][1] stores count of binary
    # strings of length i with j consecutive
    # 1's and ending at 1.
    dp = [[[0, 0] for __ in range(k + 1)]
                  for _ in range(n + 1)]
 
    # If n = 1 and k = 0.
    dp[1][0][0] = 1
    dp[1][0][1] = 1
 
    for i in range(2, n + 1):
         
        # number of adjacent 1's can not exceed i-1
        for j in range(k + 1):
            dp[i][j][0] = (dp[i - 1][j][0] +
                           dp[i - 1][j][1])
            dp[i][j][1] = dp[i - 1][j][0]
            if j >= 1:
                dp[i][j][1] += dp[i - 1][j - 1][1]
 
    return dp[n][k][0] + dp[n][k][1]
 
# Driver Code
if __name__ == '__main__':
    n = 5
    k = 2
    print(countStrings(n, k))
 
# This code is contributed by vibhu4agarwal


C#
// C# program to count number of binary strings
// with k times appearing consecutive 1's.
using System;
 
class GFG {
 
    static int countStrings(int n, int k)
    {
        // dp[i][j][0] stores count of binary
        // strings of length i with j consecutive
        // 1's and ending at 0.
        // dp[i][j][1] stores count of binary
        // strings of length i with j consecutive
        // 1's and ending at 1.
        int[,, ] dp = new int[n + 1, k + 1, 2];
 
        // If n = 1 and k = 0.
        dp[1, 0, 0] = 1;
        dp[1, 0, 1] = 1;
 
        for (int i = 2; i <= n; i++) {
 
            // number of adjacent 1's can not exceed i-1
            for (int j = 0; j < i && j < k + 1; j++) {
                dp[i, j, 0] = dp[i - 1, j, 0] + dp[i - 1, j, 1];
                dp[i, j, 1] = dp[i - 1, j, 0];
 
                if (j - 1 >= 0) {
                    dp[i, j, 1] += dp[i - 1, j - 1, 1];
                }
            }
        }
 
        return dp[n, k, 0] + dp[n, k, 1];
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int n = 5, k = 2;
        Console.WriteLine(countStrings(n, k));
    }
}
 
// This code contributed by Rajput-Ji


PHP
= 0 && isset($dp[$i][$j][1]))
                $dp[$i][$j][1] += $dp[$i - 1][$j - 1][1];
        }
    }
 
    return $dp[$n][$k][0] + $dp[$n][$k][1];
}
 
// Driver code
$n=5;
$k=2;
echo countStrings($n, $k);
     
// This code is contributed by mits
?>


Javascript


输出:

6

时间复杂度: O(n 2 )

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程