Python|DP|10 lines of code| Detailed comments
```\ndef numPermsDISequence(self, s: str) -> int:\n        n = len(s)\n        \n        # len(dp) is the length of remaining unused set as remain_set\n        
```\ndef numPermsDISequence(self, s: str) -> int:\n        n = len(s)\n        \n        # len(dp) is the length of remaining unused set as remain_set\n        # dp[i] means the last digit of any permutation formed by used set is remain_set[i]\n        # so, initially, remain_set = [0, 1, ..,n]\n        # dp[i] = 1\n        # so, the remain_set for dp[i] is [0, 1,..,i-1, i+1..n]\n        # Two edge cases:\n        # remain_set for dp[0] becomes [1, 2,..,n]\n        # remain_set for dp[n] becomes [0, 1, 2,..,n-1]\n        # for the new remain_set, dp\'s lenght becomes the length of new remain_set\n        # let\'s create a new dp1 which depends on s[0]\n        # if s[0] is \'I\',\n        # dp1[0] = dp[0] + dp[1]\n        # dp1[i] = dp[0] + dp[1] + ..+ dp[i]\n        # if s[0] is \'D\',\n        # dp1[len(remain_set)-1 # n-1] = dp[n]\n        # dp1[i] = dp[i+1] + dp[i+2] + ..+ dp[n]\n        dp = [1] * (n+1)\n        for c in s:\n            dp1 = [0]*(len(dp)-1)\n            if c == "I":\n                for i in range(len(dp1)):\n                    dp1[i] = sum(dp[:i+1])\n            else:\n                for i in range(len(dp1)-1, -1, -1):\n                    dp1[i] = sum(dp[i+1:])\n            dp = dp1\n        return dp[0] % (10**9 + 7)
[]