给定三个整数, N、K和M。任务是找出长度为N的二进制字符串的数量,这些字符串总是以1开头,其中最多可以有M个连续的 1 或 0,并且它们正好交替K次。
例子:
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
方法:由于这个问题涉及重叠子问题和最优子结构。所以,这个问题可以用动态规划来解决。
- 子问题: DP[i][j]表示长度为i的二进制字符串的数量,直到现在有j 个交替组。所以,计算dp[N][K],如果我们知道dp[nj][k-1]的值,那么我们可以很容易地通过将j=1到m(DP [N][K] 代表最终答案)。
如下递归树图中所示,观察到许多子问题重叠。因此,需要缓存结果以避免冗余计算。
- 最佳子结构:
- 通过遵循自上而下的 DP 方法:
因为我们可以有一个最多长度为M 的组,所以我们迭代每个可能的长度并使用新的N递归,并将K减少 1,作为一个新的组。子问题的解决方案被缓存并总结为最终结果dp[N][K]。 - 基本情况:
- 当 N 为 0 且 K 为 0 时,则返回 1
- 当 N 为 0 但 K 不为 0 时,则返回 0
- 当 N 不为 0 但 K 为 0 时,则返回 0
- 当两者都为负时,返回 0
下面是上述方法的实现:
C++
// C++ program to find the count
// of Binary strings of length N
// having atmost M consecutive 1s or 0s
// alternatively exactly K times
#include
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);
}
Java
// 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
Python 3
# 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
C#
// 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
Javascript
输出:
16
时间复杂度: O(N*K*M)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。