CODEFESTIVAL2018 Final G:Chicks and Cages
う
解法
dpっぽい雰囲気はあるが、何の整理もなしにはうまくいかない。まず、ある鳥かごに振り分けられたひよこの集合をとする。この鳥かごで発生するストレスの値はである。つまりストレスの値の総和は、ひよこの大きさに、そのひよこが入っている鳥かごのひよこの数を係数としてかけた値の総和ということになる。これがわかると、小さいひよこにできるだけ大きい係数を、大きいひよこにはできるだけ小さい係数をかけたくなる。実際、2つのある鳥かごに振り分けられたひよこの集合をとし、とする。このとき、かつがなりたつの組があるとき、ひよことひよこを入れかえることで、ストレスの総和を小さくできる。このことは、の小さい順にひよこを鳥かごに振り分けることで得られる最適解が存在することを意味する。
ここまでくると、を昇順にsortして、:番目のひよこを個の鳥かごを用いて振り分けたときの最小値 というdpができそうという気分になる。更新式は、の累積和をとして
である。しかしこれでは)となり間に合わない。この遷移を高速化できないだろうか?
「大きいひよこにはできるだけ小さい係数をかけたい」という気持ちを思い出そう。この気持ちに立ち返ると、が大きくなるにしたがって、調べるべきは小さくなっていくのではないか?という予想が立つ。実際、sortした後であれば、番目の鳥かごのに入ってるひよこの数をとすると、最適解においてはが成り立たなければならない。これを勘案すると、を更新する際には、の値としてまで考えれば十分であることがわかる(みたいな状況がが最大となるときに考えられる振り分け方だから)。従って更新式は
となる。このときの計算量は、計算量に調和級数が現れる形になるのでであり、十分間に合う。
実装
Submission #5713037 - CODE FESTIVAL 2018 Final
dpそのものは基本的だと思う。