Kyoto University Programming Contest 2019
オンラインでの参加でした ABC3完
レポート終わってからやり始めたら開始時点で終了まで1時間前切ってました
atcoder.jp
A - November Festival
atcoder.jp
「可能性がある」ことが判定できればいいので「残り票が全部番目に突っ込まれたら?」を考えるといいです
よってとなるようなの個数を出力すれば計算量でAC
拙解 (C++14): Submission #7960118 - Kyoto University Programming Contest 2019
B - ナップサック問題
atcoder.jp
とを必ず一緒に入れないといけないということはとはつながった一つの荷物とみなせます
UnionFind貼るなりなんなりして連結成分を求めたらそれらのとをそれぞれ足して一つの荷物にすれば普通のナップサック問題に帰着できます
この記事を参考にするなどしてのDPで解けます
拙解 (C++14): Submission #7960391 - Kyoto University Programming Contest 2019
C - てんびんばかり
atcoder.jp
問題文の式を変形すると、右の皿にg乗せるのは左の皿にg乗せるのと変わりません
また、gすべて乗せなければいけないのでg刻みの調節をするのにまずgの分銅が必要になります
そこから網羅する範囲を広げるためにはgの分銅があればもっとも広い範囲をカバーできます
そこから帰納的に考えれば
を満たす最小のが答えになることが分かります
計算量はとなってでも十分間に合います
D - Maximin Game
atcoder.jp
二人の手札のうち、小さい方から大きい方へと有向辺を伸ばすと
このようになります
ここから、どこからもアークが刺さっていないノードから順にと整数を入れていくことで手札が構築できます
つまりこのグラフをトポロジカルソートする方法は何通りあるか?がこの問題の答えです
Sの0→1または1→0で切り替わっている部分はΠorЦの字型のパスがあるのでその順番にしか入れられません
Sの0か1が連続している部分では複数の方法がありそうなので、上下に分割してみます
これを下の部分の個数が上の部分より大きくならないように左側から消していく方法が何通りあるか、を考えます
「下の部分を1つ消す」を「格子上を下に1つ進む」
「上の部分を1つ消す」を「格子上を右に1つ進む」
にそれぞれ言い換えると、
対角線を跨がずに格子点上を通って移動する経路の数え上げに帰着できました!
これはカタラン数を使って解ける典型問題なので、ランレングス圧縮してそれぞれのランの長さに対応するカタラン数を掛けていけばで解けます。
こういう典型組み合わせて解く問題コンテストでも解きたいですね
拙解 (C++14, コンテスト終了後): Submission #7960871 - Kyoto University Programming Contest 2019