1. 程式人生 > >HDU 4055 Number String

HDU 4055 Number String

c++ close ber efi print bit name its opened

題意:

給出一個長度為$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\n", res); 40 } 41 return 0; 42 }
View Code

HDU 4055 Number String