(AOJ1635) ICPC2019 国内予選-D:計数カウンタ
想定解は結構難しいと思ってしまった。
解法
「ある区間を選び、その区間の数字を同時に増やす」という操作が回であるとどういうことが起きるかを考えてみる。例えば、つのカウンタがあって、すべてが成り立っていても、両端のつはたくさん押す必要があるが、真ん中のつはほとんど押さなくてよいという状況を考えてみる。このとき、両端のつを別々に押すよりも、つ同時に押すことを何回か行った方が得をするということがあり得る。このとき真ん中のカウンタではからに戻るということが何回か起きるが、これは目標となるの値を、整数を用いてに置き換えることにしよう。解くべき問題は、「各カウンタについてをうまく選んだとき、カウンタの値をからにするには最小で何回の操作が必要か?」というものである。の値としては、カウンタの数であるまで考えれば十分である。
ところで、番目のカウンタが最適解において何回押されるかということはすぐにわかる(カウンタがつのときを考えればよいから)。番目のカウンタの状態が決まれば、のカウンタのことは考えなくてよいので、その状態において番目のカウンタを何回押すべきかも計算できる。このように考えてみると、端からdpをしたくなってくる。:「番目のカウンタまで見て、番目のカウンタの値をにするときの操作の回数の最小値」としよう。
への遷移を考えよう。基本的には、カウンタとカウンタの、各状態における押すべき回数の差分を足し合わせていくことになる。このとき、カウンタの方が押すべき回数が多いということがあり得るが、その場合はカウンタを「先に押しておいた」と解釈し、ノーコストでカウンタのときの値に遷移することで解決する。カウンタをにするためには、そのカウンタを回押す必要がある(かつの場合は除く)。この値をとしよう。からへの遷移は
となる。これでは遷移がかかり、計算量は全体でである。ICPC国内予選なら多少待てばよい(僕のチームはこれで通した)が、AOJでは通らない。
遷移を高速化しよう。上の遷移のほとんどは「無駄」である、つまり不必要な計算であることがわかる。例えば、であるでは、常にが成り立つ。つまり、への遷移はの大きい方からまでの累積minを取っておけば、で行うことができる。の方の遷移はどうだろうか。を書き下すとであり、前半項の最小値はであることを考えると、では、に遷移する際にカウンタを単独で回以上押すことになる。しかし、カウンタを単独で回押すなら、カウンタをさらに回押して損がない。つまり、であるからへの遷移は、からへの遷移に勝ることがない。従って、そのようなからの遷移は計算する必要がないことがわかった。
以上のことより、遷移として計算すべきはとだけで、これはそれぞれで可能であった。よって、dpの遷移を無事にすることができた。全体の計算量はとなり、これならAOJでも間に合う。