chinese - 中華料理 Editorial
by
kumjin3141
K理事長が食べてからの回転量の最小値を計算します。
公式解説と同様、円周上のチェックポイントを全て通過する問題に帰着します。
まず、折り返さない場合を考えます。
この場合、開始地点 \(k\) から右回り、左回りに歩いた時に最初に訪れるチェックポイントの位置を \(l, r\) とする (\(k\) を除く) と、最小値は \(N - \max(|k - l|, |k - r|)\) になります。
この値を \(\mathrm{norec}[k]\) とします。
次に、折り返す場合を考えます。公式解説と同様、折り返さない場合も含めた最小値を考えます。よって、この値が解になります。
解を \(\mathrm{ans}[k]\) とします。地点 \(k_2\) で折り返すのが最適と仮定すると、\(\mathrm{ans}[k]= \mathrm{norec}[k_2] + dist(k, k_2)\) となります。なぜなら、\(k_2\) で折り返してから、折り返す前に訪れた頂点も訪問するからです。
また、この \(k_2\) について、 \(\mathrm{ans}[k_2] = \mathrm{norec}[k_2]\) が成り立ちます。これが成り立たないと仮定すると、\(k\) から出発する時に、\(k_2\) まで行った後、\(ans[k_2]\) の経路を辿ることで、\(k_2\) から折り返さない(または複数回折り返す)真に最適な経路を作成できてしまうからです。
左回りに行ってから折り返す場合については、\(\mathrm{ans}[k] = \mathrm{ans}[k + 1] + 1\) が成り立ち、右回りについても同様のことが成り立ちます。
以上から、
\(\mathrm{ans} = \mathrm{norec}\) とした後、
\(d \in \{-1, 1\}\) について、
以下を2回繰り返す。
\(i = 1, 2, \ldots, N\) について、
\(\mathrm{ans}[i] = \min(\mathrm{ans}[i], \mathrm{ans}[i + d] + 1)\) とする
とすることで、答えを計算することができます。 \(\mathrm{norec}\) の計算は二分探索や尺取り法などで \(O(N\log N)\) や \(O(N)\) 、\(\mathrm{ans}\) の計算は \(O(N)\) でできるので、全体で \(O(N)\) や \(O(N \log N)\) で計算できました。
実装例(C++) \(\mathrm{ans}\) の計算を、念の為 5 回ほど繰り返しています。
posted:
last update:
