📌  相关文章
📜  最多具有 X 个连续 1 和 Y 个连续 0 的二进制字符串的计数

📅  最后修改于: 2022-05-13 01:56:04.263000             🧑  作者: Mango

最多具有 X 个连续 1 和 Y 个连续 0 的二进制字符串的计数

给定两个整数NM (1 ≤ N, M ≤ 100) ,分别表示10的总数。任务是计算这些01的可能排列的数量,使得任何排列最多有X个连续的1Y个连续的0 (1 ≤ X, Y ≤ 10) 。由于排列的数量可能非常大,请使用 MODULO 10 9 +7计算答案。

例子:

直觉:

  • 这个问题的基本直觉是使用递归检查所有可能的安排。
  • 这导致极高的时间复杂度。
  • 所以需要一些优化技术。
  • 选择制表。这大大降低了问题的整体复杂性。
  • 在传统的递归 + 记忆化上使用迭代方法使其更加简单。

方法:基于上述直觉,这个问题可以使用动态规划方法来解决。请按照以下步骤解决问题。

  • 使用 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)