AtCoder Beginner Contest 291 備忘録
コンテストページ: https://atcoder.jp/contests/abc291
コンテスト中AC:A〜E
Fは大方の解法まではコンテスト中に辿りついたが、最後の詰めと実装が間に合わず。コンテスト後に自力AC。
D - Flip Cards
カードの状態は表か裏かの2通りしかなく、状態数が少ないです。また、先頭(または末尾)から順に表裏を決めていくことができます。これより、DPが使えます。
番目のカードの状態がの時の、番目までのカードの表裏の状態の総数。但し、であり、の時はカードは表向き、の時はカードは裏向き
イメージとしては後述する数列の個数を数え上げる問題とみなすと良いです。
数列について、なら番目のカードは表向き、なら裏向きとします。例えば、1〜4番目のカードについて、表、裏、裏、表ならです。
この状態で、5枚目のカードを表向きにしたとすると、となり、裏向きにしたとすると、となります。
この考え方で遷移を考えると、例えば、なら、番目が表の全ての数列について、数列の末尾にを追加(すなわち、を表向きに)して新たな数列ができるので、
dp[i][0] += dp[i-1][0]
という感じで遷移できます。
初期値は、の時、との2つの数列があるので、とし、あとは0にします。
答えは、です。
実装: Submission #39251335 - AtCoder Beginner Contest 291(Sponsored by TOYOTA SYSTEMS)
E - Find Permutation
小さい順に数列の値を決定していくことを考えると、問題で与えられる大小関係に従って、決定順序を規定できます。そこで、この順序関係を有向辺とみなし、という有向辺がある有向グラフを考えます。
まず、閉路を含む場合は矛盾が生じるため解なしとなりますが、制約上このケースはありません。(余談:この記事を書いているときに制約に気づきました。)
次に、順序が同列のものが存在すると、どちらから先に値を決定してもよくなるので、を一意に特定できなくなり、Noとなります。
順序が同列のものが存在する例として、最もシンプルな形が入力例2です。
順序が同列のものが存在することの判定方法ですが、トポロジカルソートが利用できます。トポロジカルソートの詳細な説明はWebなどで検索すると出てくるため、ここでは割愛します。
トポロジカルソートで入次数0の頂点をキューに追加する際、同時に2つ以上の頂点がキューに入った場合、それらの順序を規定できません。従って、トポロジカルソートにおけるキューのサイズが2以上となったら、その時点で答えをNoにすれば良いです。
実装: Submission #39259983 - AtCoder Beginner Contest 291(Sponsored by TOYOTA SYSTEMS)
F - Teleporter and Closed off
自分より番号が大きい頂点にしか辺が無く、更に辺が各頂点で最大でも10本しかないことを利用します。
頂点を通らないことにした場合、を飛び越えるような移動は、大雑把に考えてもの範囲の頂点から、となるような頂点への移動に限定されます。つまり、
→→→
という移動経路を考えれば良いです。この際のからへの最短距離を
からへの最短距離+からへの移動距離+からへの最短距離
と分解すれば、
- 頂点から各頂点への最短距離
- 頂点からの最短距離
を予め求めておくことで、
求めたい最短距離をとして、で計算できます。
は元のグラフをBFSする事で求められ、は元のグラフの有向辺を全て逆向きにしてからBFSすることで求められます。
を固定した時の最短距離はとから出る辺を全探索すればよいです。
この計算量はのときがワーストケースですが、それでもであり、の全てについて調べてもくらいなので、間に合います。
コンテスト中は大雑把に考えていましたが、正確にはの範囲はだと思います。辺数もなので、計算量はになると思います。
実装: Submission #39279264 - AtCoder Beginner Contest 291(Sponsored by TOYOTA SYSTEMS)