Энциклопедия целочисленных последовательностей

Многие задачи в спортивном программировании из раздела динамического программирования сводятся к задаче отыскания формулы какой-либо последовательности.

Формула может быть в замкнутом виде, когда ты просто подставляешь аргументы и разом получаешь результат за время O(1), или в динамической, рекуррентной форме, когда для вычисления i-го члена надо вычислить предыдующие.

Классический пример замкнутой формы - это сумма ряда n положительных чисел:

S(n)=n*(n-1)/2.

А для динамической, или рекуррентной формы - это, например, формула для i-го члена последовательности чисел Фибонначи:

F(i)=F(i-1)+F(i-2).

Например, вот такая задача (для школьников!).

Есть N чисел от 1 до N. Требуется разместить эти числа в ряд слева направо. Первым числом всегда идет 1. Каждое последующее может отличаться от предыдущего не больше, чем на 2. Например:

1 2 3 4 5 ...
1 3 2 4 5 ...
1 3 5 4 2 ...

и т.д. (эта задача есть на Тимусе).

Требудется найти количество возможных размещений по этому правилу для N чисел. N от 1 до 55.

Просто перебором в лоб не получится, так как вариантов будет 55! ~ 10^73, а времени дается всего одна секунда.

Судя по ограничению по времени в 1 секунду, тут просто должна быть формула.

А вот теперь подходим к сути поста. Недавно я наткнулся на волшебный сайт - Онлайн-энциклопедия целочисленных последовательностей. Там ты просто вводишь несколько известных тебе членов последовательности, а сайт по большой базе данных ищет совпадения с какими-либо известными последовательностями, и в случае наличия такого совпадения, дает исчерпывающую информацию - формулы, статистический анализ и т.д.

Итак, я нашел пяток первых значений решения задачи перебором - генерировал все возможные перестановки для i членов, для i от 1 до 8, и проверяя для каждой перестановки правильность выполнения условий размещения, считал количество вариантов.

В итоге, магия произошла. Когда я ввел вычисленные первые элементы последовательности в этот анализатор, мне просто сказали, что формула для i-го члена этой последовательсти: a(n)=a(n-1)+a(n-3)+1. И все! И по данной формуле задача решается пулей одним циклом за O(N).

Конечно, для реальных соревнований такое метод не годится, так как никто не даст доступа в интернет. Да и цель задачи несколько иная - научиться выводить такие динамические соотношения самому.

А вот в жизни - бывает, что числа уже есть, и надо быстренько как-то их обсчитать на больших размерностях, вот тут и пригодится этот волшебный анализатор, которые даст исчерпывающуй информацию о ваших числах.


Оригинальный пост | Disclaimer

Комментарии