假设我们有一个字符串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