题意:
给出一个长度为$n - 1的字符串,s_i为'I', 'D', '?'$
$'I'表示a_i < a_{i + 1}$
$'D'表示 a_i > a_{i + 1}$
$'?' 表示 a_i 和 a_{i + 1} 的大小关系任意$
思路:
$dp[i][j] 表示考虑到第i位,当前位的数字位j的方案数$
$s[i - 1] == '?' 那么 dp[i][j] = sum_{k = 1}^{i - 1} dp[i - 1][k]$
$s[i - 1] == 'I' 那么 dp[i][j] = sum_{k = 1}^{j - 1} dp[i - 1][k]$
$s[i - 1] == 'D' 那么 dp[i][j] = sum_{k = j}^{k = i - 1} dp[i - 1][k]$
$第三个转移可以这样考虑,比如说之前有一个排列{1, 3, 2} 那么我当前后面插入一位2$
$我们把{1, 3, 2} 中 >= 2的数字都加1 再加入2 就变成 {1, 4, 3, 2}$
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define ll long long 5 #define N 1010 6 const ll MOD = (ll)1e9 + 7; 7 char s[N]; 8 ll f[N][N]; 9 10 int main() 11 { 12 while (scanf("%s", s + 2) != EOF) 13 { 14 f[1][1] = 1; 15 int n = strlen(s + 2) + 1; 16 for (int i = 2; i <= n; ++i) 17 { 18 if (s[i] == 'I') 19 { 20 for (int j = 1; j <= i; ++j) 21 f[i][j] = (f[i][j - 1] + f[i - 1][j - 1]) % MOD; 22 } 23 else if (s[i] == 'D') 24 { 25 for (int j = i; j >= 1; --j) 26 f[i][j] = (f[i][j + 1] + f[i - 1][j]) % MOD; 27 } 28 else 29 { 30 ll sum = 0; 31 for (int j = 1; j < i; ++j) 32 sum = (sum + f[i - 1][j]) % MOD; 33 for (int j = 1; j <= i; ++j) 34 f[i][j] = sum; 35 } 36 } 37 ll res = 0; 38 for (int i = 1; i <= n; ++i) res = (res + f[n][i]) % MOD; 39 printf("%lld ", res); 40 } 41 return 0; 42 }