競技プログラミング日記

主に AtCoder の記事です

AtCoder Beginner Contest 312D

ABC312D

DP で全探索.
\(dp_{i,x} := \) \([0,i)\) まで調べ終わって,値が \(x\) の場合の数.
ここで,( を +1, ) を -1 として,先頭から調べて累積和をとる. かっこ列になる必要十分条件は,常に和が 0 以上かつ,最後に和が 0になること.
遷移は,今調べている文字が (, ), ? で場合分け. ? のときは,次の文字が (,) で場合分け.

使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"

int main() {
  string s; cin >> s;

  ll n = s.length();


  vector<mint> dp(n+5);
  dp[0] = 1;
  rep(i,n){
    vector<mint> old(n+5);
    swap(dp, old);
    rep(x,n+1){
      if(s[i] == '('){
        dp[x+1] += old[x];
      }else if(s[i] == ')'){
        if(x-1 >= 0) dp[x-1] += old[x];
      }else{
        dp[x+1] += old[x];
        if(x-1 >= 0)dp[x-1] += old[x];
      }
    }
  }
 
  cout << dp[0].val() << endl;


  return 0;
}