Valid Permutations for DI Sequence in C++

C++Server Side ProgrammingProgramming

Suppose we have a string S. This is a string of characters from the set {'D', 'I'}. (D means "decreasing" and I means "increasing")

Now consider a valid permutation is a permutation P[0], P[1], ..., P[n] of integers {0 to n}, such that for all i, it meets these rules:

  • If S[i] == 'D', then P[i] > P[i+1];

  • Otherwise when S[i] == 'I', then P[i] < P[i+1].

We have to find how many valid permutations are there? The answer may be very large, so we will return using mod 10^9 + 7.

So, if the input is like "IDD", then the output will be 3, So there will be three different permutations, these are like (0,3,2,1), (1,3,2,0), (2,3,1,0).

To solve this, we will follow these steps −

  • n := size of S

  • Define one 2D array dp of size (n + 1) x (n + 1)

  • for initialize j := 0, when j <= n, update (increase j by 1), do −

    • dp[0, j] := 1

  • for initialize i := 0, when i < n, update (increase i by 1), do −

    • if S[i] is same as 'I', then −

      • for initialize j := 0, curr := 0, when j < n - i, update (increase j by 1), do −

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

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

    • otherwise

      • for initialize j := n - i - 1, curr := 0, when j >= 0, update (decrease j by 1), do −

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

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

  • return dp[n, 0]

Let us see the following implementation to get better understanding −

Example

 Live Demo

#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"));
}

Input

"IDD"

Output

3
raja
Updated on 04-Jun-2020 09:00:57

Advertisements