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(dD(ai))0(dD(ai))fB(i,d)={bi(dD(bi))0(dD(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(maxd[10]maxi[n1]fA(i,d),maxd[10]maxi[n1]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+maxlD(ai)maxk[i1]fB(k,l)(i1dD(ai))1(i=0dD(a0))0(dD(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+maxlD(bi)maxk[i1]fA(k,l)(dD(bi)21)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_AfBf_Bが微妙に異なるのは、bib_iを先頭にした列が作れないからである。漸化式のmaxk[i1]f(k,l)\max_{k \in [i-1]}f(k, l)の部分は数字llに対応するBITがあればO(logn){\mathcal O}(\log n)で求まるので、計20本のBITを用意することで全体としてはO(nlogn){\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を含む数であるような最長列の長さ。