Підпослідовність#44

Підпослідовність (Розбір)

Позначимо через довжину найкоротшого рядка, який не є підпослідовністю суфікса s[i \ldots n-1]. Відповідь — , а сам рядок відновлюється жадібно.

Спочатку побудуємо таблицю — найменша позиція j \ge i, у якій стоїть символ (або , якщо такого немає). Вона рахується одним проходом справа наліво за .

Тепер перехід. Нехай ми будуємо рядок і перший його символ — :

  • якщо взагалі не трапляється в , то однолітерний рядок «» уже не є підпослідовністю — вартість ;

  • інакше нехай p = \mathrm{nxt}[i][c]. Жадібне вкладення підпослідовності обов'язково візьме саме цю позицію (брати пізніше входження ніколи не вигідно), тому далі задача зводиться до суфікса s[p+1 \ldots] — вартість 1 + \mathrm{dp}[p+1].

Отже,

\mathrm{dp}[i] = \min_{c} \bigl(1 + \mathrm{dp}[\mathrm{nxt}[i][c] + 1]\bigr),

де \mathrm{dp}[n+1] вважаємо нулем (символ відсутній). База — \mathrm{dp}[n] = 1.

Відновлення відповіді. Ідемо з i = 0 і щоразу вибираємо найменший символ , на якому досягається мінімум. Це дає лексикографічно найменший рядок серед найкоротших: довжина вже зафіксована як оптимальна, тому серед усіх оптимальних продовжень вигідно взяти найменшу літеру, а далі міркування повторюється.

Складність — за часом і пам'яттю; при |s| \le 10^5 це миттєво. Якщо пам'ять критична, таблицю можна не зберігати цілком, а перераховувати на льоту, ідучи справа наліво разом із динамікою.