競技プログラミング日記

主に AtCoder の記事です

AtCoder Beginner Contest 195E

ABC195E

メモ化再帰で解くのが自然. 結果的には,for を用いた dp で解ける. 後ろから決めていくのが自然.

二人ゲームの基本に則り逆算する. ターンが交互ではなく指定されいているが,勝敗の決め方は同じ. ターンが交互ではないため,勝敗はプレイヤーを固定した方が簡単. ターンが交互の場合は,手番をもっている側の勝敗で決めると良い.
高橋君基準で勝敗を考える. 今が青木君の手番なら, 遷移先のすべてが高橋君勝利なら,今の状態は高橋君勝利. そうでなければ青木君勝利. 今が高橋君の手番なら, 遷移先のある状態が高橋君勝利なら,今の状態は高橋君勝利. そうでなければ青木君勝利.

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

// メモ化再帰
int main() {
  ll n ;
  cin >> n;
  string s,x;
  cin >> s >> x;


  vector<vector<bool>> vis(n+1, vector<bool>(7));
  vector<vector<bool>> memo(n+1, vector<bool>(7));
  auto rec = [&](auto rec, ll i, ll r) -> bool {
    if(i == n){
      return r == 0;
    }
    if(vis[i][r]) return memo[i][r];
    vis[i][r] = true;
   
    ll nr0 = (10*r) % 7;
    ll nr1 = (10*r + (s[i]-'0')) % 7;
    bool f0, f1;
    f0 = rec(rec, i+1, nr0);
    f1 = rec(rec, i+1, nr1);

    if(x[i] == 'A'){
      memo[i][r] = f0 && f1;
    }else{
      memo[i][r] = f0 || f1;
    }

    return memo[i][r]; // do not forget
  };

  takaao(rec(rec, 0, 0));


  return 0;
}