Это своего рода комментарий, но он слишком велик для комментария.
К сожалению, я не думаю, что вы можете решить эту проблему в виде алгоритма с N
, X
и Y
в качестве входных данных, потому что этих данных недостаточно. Вам нужен фактический набор орграфов, а не его размер.
Рассмотрим две похожие проблемы. Оба имеют алфавит из 2 букв (a
, b
) и N = 3
, но наборы запрещенных орграфов различны.
Задача № 1
Мы запрещаем aa
и ab
. Итак, все допустимые триплеты:
Итак, есть 3 решения
Задача № 2
Мы запрещаем aa
и bb
. Итак, все допустимые триплеты:
Есть только 2 решения.
Это происходит потому, что орграфы aa
и ab
взаимодействуют иначе, чем орграфы aa
и bb
. В частности, триплет не отфильтровывается как aa
, так и bb
одновременно, но триплет aab
отфильтровывается как aa
, так и ab
, поэтому эффективно отфильтровывается еще один триплет.
Я думаю, что может сработать использование динамического программирования по длине строки, контролирующей текущий текущий символ.
Обновление (эскиз алгоритма)
Давайте попробуем решить ее как проблему динамического программирования по всей длине строки. То, что мы хотим сохранить как состояние, это количество строк, оканчивающихся на каждый символ (таким образом, массив размером X
или словарь того же размера). Если мы найдем способ обновить такое состояние для каждого следующего размера строки, то когда мы доберемся до N
, мы можем просто суммировать значения по массиву, и это будет наш окончательный ответ.
Обновление состояния легко. Давайте рассмотрим, что происходит, когда мы добавляем новый символ в допустимую строку длиной n-1
. Мы получаем новую действительную строку длиной n
, если только последняя пара не является одним из запрещенных орграфов. Таким образом, создание нового состояния легко (вот псевдокод в стиле Python):
for prev_last_char in chars:
for new_last_char in chars:
if (prev_last_char, new_last_char) not in prohibited:
new_state[new_last_char] += old_state[prev_last_char]
Очевидно, что начальным состоянием является массив (или словарь), заполненный 1
для каждого символа.
Предполагая, что prohibited
время доступа равно O(1)
, что должно быть достигнуто с помощью словаря на основе хеша, сложность одного шага составляет O(X*X)
. Таким образом, общая сложность алгоритма составляет O(X^2*N)
.