ARC130

3完。当たり前だけど連続して黄パフォを取るのは難しい。ABがかなり簡単だったので、Cが解けてよかった。

A - Remove One Character

連続した同じ文字は条件を満たす。連続した違う文字は条件を満たさない。次に離れているものを考える。同じ文字であることは必要。その2文字よりも外側の文字は影響しない。同じ文字を取り除いて内側を考えると、最初5文字あって12345と並んでいたとして1234と2345が同じ文字列でなければならない(逆に同じ文字列なら条件を満たす)。要するに全部同じ文字ということでは?そう思ってもなかなか(同値であることの)スパッとした証明が出てこない。1文字目と2文字目が等しくなければならないというのが見えて、同じように2文字目と3文字目とかも等しい必要があるんだろうなと思ったところで切り上げて実装、提出、AC。実装ではライブラリにしておいたRunLengthを使った。

(解説を見て)自分より左の相手が何個あるかを足していくだけだった。ランレングス系は実装が大変なイメージあったけど、今回はそうでもないやつだった。実装のイメージの正確性がいまいちだなあ。

B - Colorful Lines

なんかよくあるやつに見えるけど、本当にそうだった。逆から考えれば上書きされない。行を塗るとき、その行が塗られているか、塗られていないなら列は何個塗られているか。サンプルの実行に時間がかかりソースをコメントアウトしながら二分探索するが、行とかが塗られているかのvectorを作っていた。HやWはでかいんだってば。setに書き換えて今度は大丈夫。ABCっぽい。

C - Digit Sum Minimization

桁和はそこまで大きくならない。和を9で割ったあまりとか考える。和が10になるのが一番いい。繰り上がりの連鎖が難しい。繰り上がりは固めてよさそう。繰り上げの区間を固定してから最小化しようとしてそういうことじゃなさそうと気づく。今思うと、何を最小化したいのか、どうすれば小さくなるのか、もっと早い段階でよく考えておきたかった。デフォルトで全部の数字の和と思うと、そこから繰り上がりの回数ぶん-9される、つまり求められているのは繰り上がり回数の最大化。

貪欲でいいかを考える。最初の繰り上げは10以上が必要で、そこでより小さい数字を選んで損することはなさそう(大きいものを残せば繰り上がりしやすくなる)。ここで最小費用流がちらついてくる。桁数が違うときが厄介そうだと思っていたが、違うところを0で埋めても答えが変わらなそうだと思う(0を前のほうに持ってきても得しなさそうなので)。ということで、最初の繰り上げを100通り全探索し、和が9以上になるペアの最大化は最小費用流でやる。頂点数は22。そもそも最初のa,bは数字の個数だけが必要な情報。和が9未満のペアだけコスト1をかけて全部流す。最小がわかったら、それをもう1回やって、今度は各辺の流量を見てそれがペアの個数。あとは、0より大きいものだけで和が9未満のもの、和が10以上のペア1個、0より大きいものだけで和が9以上のもの、0を含み和が9以上のもの、0を含み和が9未満のもの、の順で入れていく。明らかにもっといい解法がありそうだが、これをきっちり書けたのはよかった。

(追記)解説がわからなかったけど、解説放送でわかった。相手として和が9以上になる最小のものを選んで損しないのは知ってたけど、だから使えるものは使っていい(損しない)んだ。そうではなく相手が決まらない場合、使うことが決まっていても貪欲が進まないけど、そういうときでも(もちろん今回も)使うことにして損しない(使うことは決められる)ことに気づかなかった。何言ってんだかわからん文章になったな。

D - Zigzag Tree

要するに、各頂点に1からNまでの整数を書き深さが偶数の頂点はどの隣よりも小さくなるやつが何通りあるかの2倍。「ジグザグ列 何通り」でググってそれっぽいのがあり、パスグラフならどこをNにするか全探索すればより小さい問題に帰着できるというアイデアをもらった。全方位木DPを貼った。しかし、木なので考えるべき形がめちゃくちゃ多いことにだんだん気づいてくる(全方位の発想だとDPができない)。元々40分もなかったのでそうなると終了。