AtCoder Beginner Contest 301 メモ
コンテストページ: パナソニックグループプログラミングコンテスト2023(AtCoder Beginner Contest 301) - AtCoder
コンテスト中AC: A〜C
コンテスト後にD,Eを自力AC
D - Bitmask
以下の説明で、の最大値を十分に超えるため、最上位ビットを63としておきます。がこれより小さい場合はサイズが63になるように0を追加しておきます。
上位のビットから?のビットを決定していくことを考えます。上位ビットをできるだけ大きくした方が、値として大きくできるため、優先します。
この時、より小さい数にするために、?を使うのは高々1箇所であると言えます。なぜなら、一度未満となれば、その後の下位ビットをどのようにしたとしても、以上となることはありえないからです。
仮に番目のビットでが未満であることが確定した場合に最適解であったとします。この時、最上位ビットから番目までのビットはとで一致していることが言えます。
もし一致していなければ、番目より上位のビットでが未満であるか、より大きいかのいずれかとなってしまいます。
また、番目以降の?は全て1にするのが最適です。
を未満にするというのは、のビット目が1であり、かつ、のビット目が?である状況で、?を0にすることと言えます。
そこで、の?を1つずつ0にした場合について、その時のの最大値を全探索します。この時、
の最上位ビットからビット目までについて、?の箇所を全てと同一にし、以降は0であるような値
の0ビット目からビット目までについて、?の箇所を全て1とし、ビット目以降は0であるような値
となるように配列を作っておくと、ビット目で未満となった時の値をで計算できます。但し、便宜上、とします。(ビットを1オリジンで実装すれば-1が0になって実装しやすくなります。)
解の最大値の更新は、この値が以下である場合のみ行えばよいです。
テーブルはで構築でき、全探索もでできます。
なお、未満となる箇所が0箇所の場合も考慮する必要があります。これは、と同じです。
実装: Submission #41405709 - Panasonic Programming Contest 2023(AtCoder Beginner Contest 301)
E - Pac-Takahashi
同じお菓子を2回食べられないので、既に食べたお菓子の状態を冪集合で管理したいです。状態数分のマスを拡張したBFSはおそらく計算量的に厳しいです。
考慮すべきは、スタート-お菓子、お菓子-お菓子、お菓子-ゴール間の最短距離のみです。また、後は各状態に対する移動距離の最小値が求められればよいです。ここで思いつくのが巡回セールスマン問題です。
お菓子を頂点とみなします。また、計算量は定数倍落ちますが、実装の簡便さからスタートとゴールも頂点とみなします。
これら頂点に対する巡回セールスマン問題を考えると、状態で頂点にいる場合の最短距離を、頂点数をとしてで求めることができます。
最短距離を求めた後は、ゴールの頂点にいるdp値について、以下か調べます。以下であれば、冪集合の1の数をカウントし、更にそこからスタートとゴールの頂点数2を引いた値で、答えの最大値を更新すればよいです。
全点対間最短経路は各頂点からBFSすることで、で求められます。
実装: Submission #41471658 - Panasonic Programming Contest 2023(AtCoder Beginner Contest 301)
なお、詳細は割愛しますが、スタートとゴールは巡回セールスマン問題を解く時の頂点から除いて考えることができ、定数倍軽くなります。但し、例外処理などに気をつける必要があります。
実装: Submission #41471658 - Panasonic Programming Contest 2023(AtCoder Beginner Contest 301)