C ++中DI序列的有效排列

假设我们有一个字符串S。这是一组{'D','I'}中的字符串。(D表示“减少”,而我的意思是“增加”)

现在考虑一个有效的排列是整数{0到n}的排列P [0],P [1],...,P [n],这样对于所有i,它都满足以下规则:

  • 如果S [i] =='D',则P [i]> P [i + 1];

  • 否则,当S [i] =='I'时,则P [i] <P [i + 1]。

我们必须找到多少个有效排列?答案可能非常大,因此我们将使用mod 10 ^ 9 + 7返回。

因此,如果输入类似于“ IDD”,那么输出将为3,因此将存在三个不同的排列,例如(0,3,2,1),(1、3、2、0),( 2,3,1,0)。

为了解决这个问题,我们将遵循以下步骤-

  • n:= S的大小

  • 定义一个大小为(n + 1)x(n + 1)的2D数组dp

  • 对于初始化j:= 0,当j <= n时,更新(将j增加1),执行-

    • dp [0,j]:= 1

  • 对于初始化i:= 0,当i <n时,更新(将i增加1),执行-

    • 对于初始化j:= n-i-1,curr:= 0,当j> = 0时,更新(将j减1),-

    • curr:=(dp [i,j + 1] + curr)mod m

    • dp [i + 1,j] =(dp [i + 1,j] + curr)

    • 对于初始化j:= 0,curr:= 0,当j <n-i时,更新(j增加1),-

    • curr:=(dp [i,j] + curr)mod m

    • dp [i + 1,j] =(dp [i + 1,j] + curr)

    • 如果S [i]与“ I”相同,则-

    • 除此以外

    • 返回dp [n,0]

    让我们看下面的实现以更好地理解-

    示例

    #include <bits/stdc++.h>
    using namespace std;
    const int m = 1e9 + 7;
    class Solution {
       public:
       int numPermsDISequence(string S) {
          int n = S.size();
          vector<vector<int>> dp(n + 1, vector<int>(n + 1));
          for (int j = 0; j <= n; j++)
          dp[0][j] = 1;
          for (int i = 0; i < n; i++) {
             if (S[i] == 'I') {
                for (int j = 0, curr = 0; j < n - i; j++) {
                   curr = (dp[i][j] + curr) % m;
                   dp[i + 1][j] = (dp[i + 1][j] + curr) % m;
                }
             } else {
                for (int j = n - i - 1, curr = 0; j >= 0; j--) {
                   curr = (dp[i][j + 1] + curr) % m;
                   dp[i + 1][j] = (dp[i + 1][j] + curr) % m;
                }
             }
          }
          return dp[n][0];
       }
    };
    main(){
       Solution ob;
       cout << (ob.numPermsDISequence("IDD"));
    }

    输入项

    "IDD"

    输出结果

    3