競技プログラミング日記

主に AtCoder の記事です

第九回 アルゴリズム実技検定 H問題

 

PAST009H

LCSと同様. \(s,t\) の最後の文字 \(s_{i}, t_{j}\) を使うかどうかで場合分け. \(s_{[0,i)}, t_{[0,j)}\) に対する答えを \(dp_{i,j}\) とおく.

  • \(s_{i} \neq t_{j}\) のとき:使った方が良い. 言い換えると,使う最適な選び方が存在する. このとき\(dp_{i,j} + 1\) .
  • \(s_{i} = t_{j}\)のとき: どちらかは使えない.
    • \(s_{i}\) を使わない場合: \(dp_{i,j+1}\).
    • \(t_{j}\) を使わない場合: \(dp_{i+1,j}\).

初期化
\(i,j\) のどちらかが \(0\) のとき, \(dp_{i,j} = 0\) になる.

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

int main() {
  string s,t; cin >> s >> t;
  ll n = s.length(), m = t.length();
 
  vvll dp(n+1, vll(m+1, 0));
  rep(i,n+1) dp[i][0] = 0;
  rep(j,m+1) dp[0][j] = 0;

  rep(i,n){
    rep(j,m){
      ll now = dp[i][j];
      ll* ne = &dp[i+1][j+1];

      if(s[i] != t[j]){
        // i,jを使う
        chmax(*ne, now + 1);
      }else{
        // i,jを使わない
        // i.e. i を使わない または jを使わない
        chmax(*ne, dp[i][j+1]);
        chmax(*ne, dp[i+1][j]);
      }
    }
  }
  cout << dp[n][m] << endl;

  return 0;
}