Official

J - 巡回する屋台 / Traveling Stall Editorial by kyopro_friends


\(O(2^MMN^2)\) 解法

高橋君の状態は「現在位置」と「すでに買い物をした屋台の集合」により表すことができます。
よって \(\mathrm{dp}[S][x]\) を「すでに買い物をした屋台の集合が \(S\) の状態で座標 \(x\) にいるときの時刻の最小値」とするDPにより答えを求めることができそうです。

遷移として「次にどの屋台からどの位置で買い物をするか」を全て試すことにします。屋台 \(i\) が時刻 \(t\) 以降に座標 \(x\) にやってくる最小時刻を \(f(i,x,t)\) とすると、

\(\mathrm{dp}[S\cup\{i\}][x']\xleftarrow{\text{chmin}}f(i,x,\mathrm{dp}[S][x]+|x-x'|)\)

を全ての \((i,x')\) について行うという配るDPができます。
屋台がある区画を訪れる間隔は高々 \(N\) であることから、予め全ての屋台について時刻 \(2N\) までの位置をシミュレーションしておくことで、各区画にやってくる周期がわかり、\(f(i,x,t)\)\(O(1)\) で計算することができます。

以上より、状態数 \(O(2^MN)\) 、遷移 \(O(MN)\)\(O(2^MMN^2)\) でこの問題を解くことができました。

\(O(2^MN^2\log N)\) 解法

\(\mathrm{dp}[t][S][x]\) を「すでに買い物をした屋台の集合が \(S\) の状態で時刻 \(t\) に座標 \(x\) にいることができるか?」を表す真偽値とします。
屋台の移動は \(O(N)\) の周期を持つことから、「時刻 \(t\) に座標 \(x\) にいる屋台の集合」は \(O(NM)\) の前計算によりただちに得ることができます。
よって \(\mathrm{dp}[t][*][*]\) から \(\mathrm{dp}[t+1][*][*]\) への遷移は、各状態から高橋くんの移動方法3通りをそれぞれ調べる配るDPにより \(O(2^MN)\) 時間で行うことができます。
この問題の答えは \(O(N\log N)\) になることから、\(O(2^MN^2\log N)\) でこの問題を解くことができました。

答えが \(O(N\log N)\) になることの証明 区画 \(x\)\(\left\lceil\frac{N}{x}\right\rceil\) 回留まりながら区画 \(1,2,\dots,N\) の順に移動することを考えます。これは \(O(N\log N)\) 回の行動からなります。この行動で全ての屋台から買い物ができることを示します。
各屋台 \(i\) について\(g_i=\gcd(D_i,N)\) とすると、屋台 \(i\)\(g_i\) 個の区画 \(1,2,\dots,g_i\) のうちちょうど 1 つに、\(\frac{N}{g_i}\) 時間おきにやってきます。高橋君は区画 \(1,2,\ldots,g\) の全てに \(\frac{N}{g}\) 回以上連続して留まっているので、その過程のどこかでこの屋台から買い物をすることができます。
この証明は MMNMMさんによるものです

\(O(2^MN^2)\) 解法

高橋君の状態は「現在位置」「すでに買い物をした屋台の集合」により表すことができます。
また、全ての屋台の移動は \(N\) の周期を持つことから、時刻を \(\bmod N\) で考えることで、 \(\mathrm{dp}[t][S][x]\) を「すでに買い物をした屋台の集合が \(S\) の状態で、時刻が \(\bmod N\)\(t\) で座標 \(x\) にいるときの時刻の最小値」とするDPにより答えを求めることができそうです。
遷移としては、高橋君の移動方法3通りをそれぞれ調べます。 屋台の移動は \(N\) の周期を持つことから、「時刻 \(t\) に座標 \(x\) にいる屋台の集合」は \(O(NM)\) の前計算によりただちに得ることができます。
DPの遷移において時刻はちょうど1増えるので、DPテーブルを埋めることはBFSででき、状態数 \(O(2^MN^2)\) 、遷移 \(O(1)\) であることから、\(O(2^MN^2)\) でこの問題を解くことができました。

posted:
last update: