Вроде бы константу можно улучшить до
.
В изложенных алгоритмах никак не учитывался свет в вагоне при "прямом" проходе. Типичный ход - идем вперед
шагов и выключаем свет. Идем обратно
шагов. Если свет выключен, то включаем, в противном случае найден цикл.
Однако, если во всех вагонах где я побывал свет горит, а я попал в вагон без света, то цикл гарантированно длиннее. Идея и заключается в том, чтобы оставлять за собой определенную комбинацию освещения так, чтобы в некоторых случаях можно было бы сразу отбросить вариант зацикливания. Заменим выражение свет горит или не горит на 1 и 0.
Пусть мне уже известна цепочка из
вагонов такая, что
1. Длина поезда гарантированно не меньше
2. Свет горит во всех вагонах кроме второго.
Графически это можно изобразить как последовательность из 0 и 1.
Например
1 0 1 1 1
Что происходит дальше? Мы будем проверять дальше вагоны, при этом независимо ни от чего свет в вагоне будем включать(устанавливать в 1). Это гарантирует, что если цикл не найден, то выполнено условие 2.
Итак, в данный момент я знаю, что длина цикла может быть только
.
А. Проверяем следующий вагон.
Б. Там 0. Значит цикл длины
невозможен. Выставляю 1 (как уже упоминалось), заменяю
и иду в шаг А.
В. Там 1. Никакой новой информации. Идем в следующий шаг.
Г. Проверяем следующий вагон. Возникает два подварианта.
Г1. Там 1. Ага, цикл длины
невозможен, а возможны только
. Заменяю
и иду в шаг Г (как после шага В).
Г2. Там 0. Это значит, что возможен цикл длины
или
. Но невозможен цикл длины
. Включаю свет и иду в следующий шаг.
Д. Для некоторого
один за другим проверяю
вагонов.
Если напарываюсь на 0, то "короткие" циклы невозможны и я попадаю в ситуацию варианта Б. К этому моменту имеется
просмотренных вагонов и длина цикла не меньше
. Поэтому полагаем
и идем в шаг Д.
Е. Итак просмотрено
вагонов. При этом либо цикл имеет длину
и тогда во всех вагонах горит свет, поскольку единственный вагон (номер 2) без света мы "ликвидировали" на шаге Г2. Либо цикл имеет длину не меньше чем
. Проверяем гипотезу
. Для этого выставим в вагоне 0, сбегаем на
вагонов назад. Если там 0 - то цикл найден, если нет то возвращаемся туда где были (еще
шагов). При этом
. В этот момент мы тратим либо
шагов и задача решена, либо
шагов и задача продолжается с
. И вот тут надо грамотно выбрать
. Отмечу, что
соответствует предыдущим схемам и дает константу 5. Однако, для
константа равна
.
Пусть
общее кол-во просмотров вагонов к моменту шага А.
Для получения нужной оценки достаточно по индукции доказать, что
. Если будет найден цикл длины
, то на это будет затрачено
просмотров. В противном случае будет затрачено
просмотров, а
увеличится до
.
Это кажется странным, что "лишние" проверки (почти в полтора раза) могут ускорить алгоритм. Однако они позволяют "резко" увеличить оценку снизу для длины цикла (если гипотеза провалилась), что и приводит к выигрышу.