geam1113’s diary

主にAtcoderのコンテストの備忘録を書きます。AtCoder緑と水色を行ったり来たりしています。

AtCoder Beginner Contest 291 備忘録

コンテストページ: https://atcoder.jp/contests/abc291
コンテスト中AC:A〜E
Fは大方の解法まではコンテスト中に辿りついたが、最後の詰めと実装が間に合わず。コンテスト後に自力AC。

D - Flip Cards

カードの状態は表か裏かの2通りしかなく、状態数が少ないです。また、先頭(または末尾)から順に表裏を決めていくことができます。これより、DPが使えます。

dp[i][j]:=i番目のカードの状態がjの時の、i番目までのカードの表裏の状態の総数。但し、j=\{0,1\}であり、j=0の時はカードは表向き、j=1の時はカードは裏向き

イメージとしては後述する数列Tの個数を数え上げる問題とみなすと良いです。

数列Tについて、T_i=0ならi番目のカードは表向き、T_i=1なら裏向きとします。例えば、1〜4番目のカードについて、表、裏、裏、表ならT=\{0,1,1,0\}です。

この状態で、5枚目のカードを表向きにしたとすると、T=\{0,1,1,0,0\}となり、裏向きにしたとすると、T=\{0,1,1,0,1\}となります。

この考え方で遷移を考えると、例えば、A_{i-1}\neq A_iなら、i-1番目が表の全ての数列について、数列の末尾に0を追加(すなわち、A_iを表向きに)して新たな数列ができるので、
dp[i][0] += dp[i-1][0]
という感じで遷移できます。

初期値は、i=1の時、\{0\}\{1\}の2つの数列があるので、dp[1][0]\leftarrow 1,\ dp[1][1]\leftarrow 1とし、あとは0にします。

答えは、dp[N][0]+dp[N][1]です。

実装: Submission #39251335 - AtCoder Beginner Contest 291(Sponsored by TOYOTA SYSTEMS)

E - Find Permutation

小さい順に数列の値を決定していくことを考えると、問題で与えられる大小関係に従って、決定順序を規定できます。そこで、この順序関係を有向辺とみなし、X_i \rightarrow Y_iという有向辺がある有向グラフを考えます。

まず、閉路を含む場合は矛盾が生じるため解なしとなりますが、制約上このケースはありません。(余談:この記事を書いているときに制約に気づきました。)

次に、順序が同列のものが存在すると、どちらから先に値を決定してもよくなるので、Aを一意に特定できなくなり、Noとなります。
順序が同列のものが存在する例として、最もシンプルな形が入力例2です。

順序が同列のものが存在することの判定方法ですが、トポロジカルソートが利用できます。トポロジカルソートの詳細な説明はWebなどで検索すると出てくるため、ここでは割愛します。

トポロジカルソートで入次数0の頂点をキューに追加する際、同時に2つ以上の頂点がキューに入った場合、それらの順序を規定できません。従って、トポロジカルソートにおけるキューのサイズが2以上となったら、その時点で答えをNoにすれば良いです。

実装: Submission #39259983 - AtCoder Beginner Contest 291(Sponsored by TOYOTA SYSTEMS)

F - Teleporter and Closed off

自分より番号が大きい頂点にしか辺が無く、更に辺が各頂点で最大でも10本しかないことを利用します。

頂点kを通らないことにした場合、kを飛び越えるような移動は、大雑把に考えてもmax(k-10,1) \leq u \lt kの範囲の頂点uから、v\gt kとなるような頂点vへの移動に限定されます。つまり、

1uvN

という移動経路を考えれば良いです。この際の1からNへの最短距離を

1からuへの最短距離+uからvへの移動距離+vからNへの最短距離

と分解すれば、

  • 頂点1から各頂点への最短距離d^1_i
  • 頂点Nからの最短距離d^N_i

を予め求めておくことで、

求めたい最短距離をd^1_u + 1+d^N_vとして、O(1)で計算できます。

d^1は元のグラフをBFSする事で求められ、d^Nは元のグラフの有向辺を全て逆向きにしてからBFSすることで求められます。

kを固定した時の最短距離はuuから出る辺を全探索すればよいです。
この計算量はM=10のときがワーストケースですが、それでも10^2であり、2\leq k \leq N-1の全てについて調べても10^7くらいなので、間に合います。

コンテスト中は大雑把に考えていましたが、正確にはuの範囲はmax(k-M-1,1) \leq u \lt kだと思います。辺数もMなので、計算量はO(NM^2)になると思います。

実装: Submission #39279264 - AtCoder Beginner Contest 291(Sponsored by TOYOTA SYSTEMS)