Educational DP Contest / DP まとめコンテスト V - Subtree
解法
全方位木dpをします。
初めに頂点1が根である際の値を求めます。
を根とする部分木について、を黒で塗った際の部分木の塗り方
とすると、頂点の子の集合をとして、
となります。
を根とした際の求めるべき答え
とすると、
となります。
が求まっている際に、その子であるについての答えを求めるため、へシフトすることを考えます。
書き換えるべき場所は、とのみになります。
については、定義に基づいて計算すればよいので、を求めることのみ考えます。
となるので、あとはこれを計算すればよいのですが、愚直に計算をすると間に合いません。
ある数列について、を高速に計算する方法を考えます。
これは、累積和同様に数列の前方からの累積積と、後方からの累積積をあらかじめ計算しておくと、それぞれの累積積について、番目の手前の値をかけ合わせることで、前計算のみで、で計算することができます。
あとは、これを利用することで、dfsを行いつつ、根の付け替えを行い答えを求めることができます。
感想
全方位木の概要は知っていたので考察はすんなり進んだのですが、累積積を利用する部分を思いつくのが難しかったです…
ARC064 E - Cosmic Rays
解法
あるバリア内は好きな座標に移動できます。
ので、あるバリアから、別のバリアへと移動することを考えます。
そのとき、2つのバリアについて重複する箇所が存在すれば、そのバリア同士は自由に行き来することができます。そうでないときは、2つの円の最短距離を求めれば、その距離の部分のみ、宇宙線を浴びることになります。それよりも短い距離で2つのバリアを行き来することはできません。
結局、2つのバリアの距離は、
で求めることができ、また、2つのバリアで重複箇所がある場合は、この値が0以下になるので、最終的に、2つのバリアを行き来する際に浴びる宇宙線の時間は
となります。
スタート地点、ゴール地点は、中心座標そのまま、半径が0の円とみなすことができるので、あとは、個のバリアについて、任意のバリアのペアを行き来した際に浴びる宇宙線の時間を計算してそれをコストとしつつ、ダイクストラ法を用いることで、スタート地点からゴール地点へ行く際に浴びる宇宙線の時間の最小値が求まります。
AOJ 1232 - Calling Extraterrestrial Intelligence Again
問題概要
3つの整数が与えられます。
かつとなるようなのうち、が最大となるようなペアを求めてください。
制約は、です。
解法
まずはエラトステネスの篩を利用して、素数を洗い出します。
について全探索をすると、の最適解は、あるに対して、
、を満たすような最大の素数になります。
ので、二分探索での最大値を毎回求め、答えを求めていけばよいです。
のですが、AC後に他の解説ブログを見たところ、という制約のおかげで、も全探索できるらしいです…ちょうど調和級数の形になりますね。
感想
篩で洗い出す素数の個数を2回間違えました(最初は少なすぎてWAが出て、その後増やしすぎてTLEになりました)…反省します。
ABC142 F - Pure
解法
方法は、番目から番目に戻ってくるサイズが最小の閉路について、問題の条件を満たしているかどうか調べる、というものです。
これを全てのについて調べ、存在すればそれを答えればよいです。
何故なら、与えられたグラフの中で、最小のサイズの閉路を見つけると、それが問題の条件を満たすグラフになるからです。
まず、問題の条件を満たす閉路が1つあったとします。
そこに、辺を1つ追加すると、その閉路は問題の条件を満たさなくなってしまいます。
しかし、その閉路についてよく見ると、追加した辺を上手く使うことで、問題の条件を満たすような閉路が必ずどこかに存在しています。
例えば、黄色と青の辺からなる、問題の条件を満たす閉路が存在したときに、橙の辺を追加したとしても、黄色+橙の辺と、それにつながってる頂点のみを選ぶことで再び問題の条件を満たす閉路が完成します。
こうして完成した閉路に、適当な頂点と辺を追加したものが問題で入力されるグラフになるので、この一番小さい閉路を探せばよいことになります。
そして、それは上記の方法で求めることができます。
具体的には、閉路を探すパートについてはBFSとその復元(1つ前に通った頂点をメモしておく)を行い、問題の条件を満たすかどうか検査するパートでは、選んだ閉路につながっている辺についてチェックし、どこかで出次数か入次数が2以上になっている頂点が存在しないか見ればよいです。
結果的にはぐらいで解けます。
感想
上手い実装方法がわからなかったのでこうなりましたが、バグなくかけたのでまぁ良かったです。
ABC142 E - Get Everything
解法
制約がbitDPをしろと言っているので、bitDPをします。
現在開けた宝箱の状態がのときに、そこからかかる費用の最小値
とします。
を整数型の変数1つで表し、2進数の桁に宝を割り振り、0:まだ開いていない、1:開いている、とすると
初期値はで、答えはです。
を求めることについて考えると、
状態がの際に番目の鍵を使うと、 (ただし、は番目の鍵を使用して開けることのできる宝箱の集合)
となります。
鍵は種類あり、これを全部試せばよく、
となります。のパターンは注意する必要があり、スルーしなければなりません。
あとはこれを繰り返せば答えが求まります。
なのですが、を前計算してあげるとになります(自分は前計算してないです)
感想
久々にbitDPを見た気がします…
やっぱりbitDPに関しては再帰で書くのが個人的には好きです