2019年3月21日木曜日

CS Academy FIICode 2019 Round #3 - Array Macao

CS Academy FIICode 2019 Round #3 - Array Macao

しょうもないバグで間に合わなかったのだが、想定解より遅い方法を取ってしまったのでメモしておく。以下、すべて0-basedとし、整数kkの10進表示に含まれる数字の集合をD(k)D(k)とする。

fA(i,d)={aiを末尾とする最長列の長さ(d∈D(ai))0(d∉D(ai))fB(i,d)={biを末尾とする最長列の長さ(d∈D(bi))0(d∉D(bi)) f_A(i, d) = \begin{cases} a_i を末尾とする最長列の長さ & (d \in D(a_i)) \\ 0 & (d \notin D(a_i)) \end{cases} \\ f_B(i, d) = \begin{cases} b_i を末尾とする最長列の長さ & (d \in D(b_i)) \\ 0 & (d \notin D(b_i)) \end{cases}

とすると、答えは
max⁡(max⁡d∈[10]max⁡i∈[n−1]fA(i,d),max⁡d∈[10]max⁡i∈[n−1]fB(i,d))\max (\max_{d \in [10]} \max_{i \in [n-1]} f_A(i, d), \max_{d \in [10]} \max_{i \in [n-1]} f_B(i, d))
であり、漸化式は次のように書ける。

fA(i,d)={1+max⁡l∈D(ai)max⁡k∈[i−1]fB(k,l)(i≥1かつd∈D(ai))1(i=0かつd∈D(a0))0(d∉D(ai)) f_A(i, d) = \begin{cases} 1+ \max_{l \in D(a_i)} \max_{k \in [i-1]} f_B(k, l) & (i \ge 1 かつ d \in D(a_i)) \\ 1 & (i = 0 かつ d \in D(a_0)) \\ 0 & (d \notin D(a_i)) \end{cases} \\
fB(i,d)={1+max⁡l∈D(bi)max⁡k∈[i−1]fA(k,l)(d∈D(bi)かつ第2項≥1)0(それ以外) f_B(i, d) = \begin{cases} 1+ \max_{l \in D(b_i)} \max_{k \in [i-1]} f_A(k, l) & (d \in D(b_i) かつ第2項\ge 1)\\ 0 & (それ以外)\\ \end{cases}

fAf_AとfBf_Bが微妙に異なるのは、bib_iを先頭にした列が作れないからである。漸化式のmax⁡k∈[i−1]f(k,l)\max_{k \in [i-1]}f(k, l)の部分は数字llに対応するBITがあればO(log⁡n){\mathcal O}(\log n)で求まるので、計20本のBITを用意することで全体としてはO(nlog⁡n){\mathcal O}(n \log n)になる。(350msくらいでAC。)

しかし、解説にある通り、以下の通りにDPすればO(n){\mathcal O}(n)で求まるはず。

fA(k,d)=f_A(k, d) = 問題を{0,...,k}\{0, ..., k\}に制限したとき、末尾が(ai)i∈[k](a_i)_{i \in [k]}から選ばれていてかつ数字ddを含む数であるような最長列の長さ。

fB(k,d)=f_B(k, d) = 問題を{0,...,k}\{0, ..., k\}に制限したとき、末尾が(bi)i∈[k](b_i)_{i \in [k]}から選ばれていてかつ数字ddを含む数であるような最長列の長さ。