最多具有 X 个连续 1 和 Y 个连续 0 的二进制字符串的计数
给定两个整数N和M (1 ≤ N, M ≤ 100) ,分别表示1和0的总数。任务是计算这些0和1的可能排列的数量,使得任何排列最多有X个连续的1和Y个连续的0 (1 ≤ X, Y ≤ 10) 。由于排列的数量可能非常大,请使用 MODULO 10 9 +7计算答案。
例子:
Input: N = 2, M = 3, X = 1, Y = 2
Output: 5
Explanation: All arrangements: 11000, 10100, 10010, 10001, 01100, 01010, 01001, 00110, 00101, 00011.
Out of these arrangements the valid arrangements are: 10100, 10010, 01010, 01001, 00101
So the number of arrangements possible are 5.
Input: N = 2, M = 2, X = 1, Y = 1
Output: 2
直觉:
- 这个问题的基本直觉是使用递归检查所有可能的安排。
- 这导致极高的时间复杂度。
- 所以需要一些优化技术。
- 选择制表。这大大降低了问题的整体复杂性。
- 在传统的递归 + 记忆化上使用迭代方法使其更加简单。
方法:基于上述直觉,这个问题可以使用动态规划方法来解决。请按照以下步骤解决问题。
- 使用 3D 网格来存储以下{count of 1s, count of 0s, 表示最后使用的值(如果 A,则为 0,如果 B,则为 1) }
- 对 1 和 0 使用嵌套循环。
- 在嵌套循环的每次迭代中, (i 表示 1s,j 表示 0s)
- 如果在当前序列上加1 ,则将i – k 组成的序列个数相加,(1 ≤ k ≤ X) 1,以 0 结尾。
- 如果在当前序列中加了0 ,则加入由j – k 组成的序列个数,(1 ≤ k ≤ Y) 0s 并以 1s 结尾。
- 这给出了 i 1s 和 j 0s 序列的每次迭代的答案。
下面是上述方法的实现。
C++
// C++ code to implement above approach
#include
using namespace std;
// Functiont to calculate
// total possible arrangements
int totalArrangements(int N, int M,
int X, int Y)
{
int dp[N + 1][M + 1][2];
int mod = 1000000007;
for (int i = 0; i <= N; i++) {
for (int j = 0; j <= M; j++) {
dp[i][j][0] = 0;
dp[i][j][1] = 0;
}
}
dp[0][0][0] = 1;
dp[0][0][1] = 1;
for (int i = 0; i <= N; i++) {
for (int j = 0; j <= M; j++) {
for (int k = 1; k <= X; k++) {
if (i >= k) {
dp[i][j][1]
+= dp[i - k][j][0];
dp[i][j][1] %= mod;
}
}
for (int k = 1; k <= Y; k++) {
if (j >= k) {
dp[i][j][0]
+= dp[i][j - k][1];
dp[i][j][0] %= mod;
}
}
}
}
return ((dp[N][M][0] + dp[N][M][1]) % mod);
}
// Driver code
int main()
{
int N = 2, M = 3, X = 1, Y = 2;
cout << totalArrangements(N, M, X, Y);
return 0;
}
Java
// Java code for the above approach
import java.util.*;
class GFG{
// Functiont to calculate
// total possible arrangements
static int totalArrangements(int N, int M,
int X, int Y)
{
int dp[][][] = new int[N + 1][M + 1][2];
int mod = 1000000007;
for (int i = 0; i <= N; i++) {
for (int j = 0; j <= M; j++) {
dp[i][j][0] = 0;
dp[i][j][1] = 0;
}
}
dp[0][0][0] = 1;
dp[0][0][1] = 1;
for (int i = 0; i <= N; i++) {
for (int j = 0; j <= M; j++) {
for (int k = 1; k <= X; k++) {
if (i >= k) {
dp[i][j][1]
+= dp[i - k][j][0];
dp[i][j][1] %= mod;
}
}
for (int k = 1; k <= Y; k++) {
if (j >= k) {
dp[i][j][0]
+= dp[i][j - k][1];
dp[i][j][0] %= mod;
}
}
}
}
return ((dp[N][M][0] + dp[N][M][1]) % mod);
}
// Driver Code
public static void main(String[] args)
{
int N = 2, M = 3, X = 1, Y = 2;
System.out.print(totalArrangements(N, M, X, Y));
}
}
// This code is contributed by sanjoy_62.
Python3
# Python code to implement above approach
# Functiont to calculate
# total possible arrangements
def totalArrangements(N, M, X, Y):
dp = [[[0 for i in range(2)] for j in range(M + 1) ] for k in range(N + 1)]
mod = 1000000007;
for i in range(N + 1):
for j in range(M + 1):
dp[i][j][0] = 0;
dp[i][j][1] = 0;
dp[0][0][0] = 1;
dp[0][0][1] = 1;
for i in range(N + 1):
for j in range(M + 1):
for k in range(1, X + 1):
if (i >= k):
dp[i][j][1] += dp[i - k][j][0];
dp[i][j][1] %= mod;
for k in range(1, Y + 1):
if (j >= k):
dp[i][j][0] += dp[i][j - k][1];
dp[i][j][0] %= mod;
return ((dp[N][M][0] + dp[N][M][1]) % mod);
# Driver code
N = 2
M = 3
X = 1
Y = 2;
print(totalArrangements(N, M, X, Y));
# This code is contributed by gfgking
C#
using System;
public class GFG{
// Functiont to calculate
// total possible arrangements
static int totalArrangements(int N, int M,
int X, int Y)
{
int[,,] dp = new int[N + 1, M + 1, 2];
int mod = 1000000007;
for (int i = 0; i <= N; i++) {
for (int j = 0; j <= M; j++) {
dp[i, j, 0] = 0;
dp[i, j, 1] = 0;
}
}
dp[0, 0, 0] = 1;
dp[0, 0, 1] = 1;
for (int i = 0; i <= N; i++) {
for (int j = 0; j <= M; j++) {
for (int k = 1; k <= X; k++) {
if (i >= k) {
dp[i, j, 1]
+= dp[i - k, j, 0];
dp[i, j, 1] %= mod;
}
}
for (int k = 1; k <= Y; k++) {
if (j >= k) {
dp[i, j, 0]
+= dp[i, j-k, 1];
dp[i, j, 0] %= mod;
}
}
}
}
return ((dp[N, M, 0] + dp[N, M,1]) % mod);
}
// Driver code
static public void Main ()
{
int N = 2, M = 3, X = 1, Y = 2;
Console.WriteLine(totalArrangements(N, M, X, Y));
}
}
// This code is contributed by hrithikgarg03188.
Javascript
输出
5
时间复杂度: O(N * M * (X+Y))。
辅助空间: O(N * M)