UVa 11982 - Fantasy Cricket (dp)
阿新 • • 發佈:2021-08-07
題目連結:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=0&problem=3133&mosmsg=Submission+received+with+ID+26662619
如果該位置為 \('D'\),說明這個位置應該向前放,如果為 \('U'\),則說明應該向後放,如果為 \('E'\),則說明原地不動
於是可以設計出狀態,\(dp[i][j]\) 表示前 \(i\) 個人,有 \(j\) 個 \(U\) 的位置還沒有放下,轉移分之前的 \('U'\)
轉移方程為 :
\[ \begin{cases} dp[i][j] = dp[i-1][j], &s[i] == 'E' \\ dp[i][j] = dp[i-1][j] * j + dp[i-1][j-1], &s[i] == 'U' \\ dp[i][j] = dp[i-1][j] * j + dp[i-1][j+1] * (j+1) * (j+1), &s[i] == 'D' \end{cases} \]#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1010; const int M = 1000000007; int T, n; int dp[maxn][maxn]; char s[maxn]; ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; } int main(){ scanf("%d", &T); for(int kase = 1 ; kase <= T ; ++kase){ scanf("%s", s + 1); n = strlen(s + 1); memset(dp, 0, sizeof(dp)); dp[0][0] = 1; for(int i = 1 ; i <= n ; ++i){ for(int j = 0 ; j <= i ; ++j){ if(s[i] == 'E'){ dp[i][j] = dp[i-1][j]; } else if(s[i] == 'U'){ dp[i][j] = 1ll * dp[i-1][j] * j % M; if(j > 0) dp[i][j] = (dp[i][j] + dp[i-1][j-1]) % M; } else{ dp[i][j] = (1ll * dp[i-1][j] * j % M + 1ll * dp[i-1][j+1] * (j+1) % M * (j+1) % M) % M; } } } printf("Case %d: %d\n", kase, dp[n][0]); } return 0; }