2020年9月14日月曜日

CodeChef September Challenge 2020 - Divide Candies

べき乗和はKKの値に関わらず奇数と偶数を交互に足すので、総和は奇、奇、偶、偶、奇、奇、……となる。総和が奇/偶の時の自明な下限がそれぞれ1/0なので、これを達成できれば最善となる。実験してみると、NNが十分に大きければ常に下限が達成できるという予想が立つ。

K=1K=1の場合、長さ4の区間は01100110とわければよくて、NN44の倍数ならこれに従って等分できる。倍数でない場合もそれぞれ4つずつ等分した後、残りを適当にわければよい。

K=2K=2について。また実験すると、長さ8の区間は0110100101101001で等分できることがわかるので、NNが小さい場合の構成を列挙した上で、以降は88個ずつ等分すればよい。

K=3,4K=3, 4の場合も常に等分できるような長さの区間が見つかれば解決しそうだ。

K=3K=3の場合は長さ16の区間は01101001100101100110100110010110で等分できる。(ここでようやく、ひとつ小さい次数で得た列をflipしてくっつければよいことに気づく。)やはりNNが小さい場合を列挙して、以降は1616個ずつ等分すればよい。K=4K=4も同様で、長さ32の区間を0110100110010110100101100110100101101001100101101001011001101001で等分できる。

さて、NNが小さい場合の解を用意する必要があるのだが、明らかにIPソルバで解けるのでOR-ToolsのCP-SATを使った。K=3K=3までは愚直でいいとして、K=4K=4はDPや半分全列挙でも簡単ではないように見える。(ちゃんと考えていない)