Re[2]: Помогите ускорить алгоритм
От: Кузнец Россия  
Дата: 30.03.16 22:46
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, Кузнец, Вы писали:


К>>Задача такова. Дан набор "запрещённых" слов, нужно подсчитать количество слов длины N, таких, что они не содержат подстрок, которые были бы среди запрещённых.


К>>Например, если запрещены строки ab, dbc, то допустимы строки типа b, ac, dba.


К>>Ограничения на размер входа таковы, что сгодится в худшем случае квадратичный алгоритм (по суммарному размеру запрещённых строк, он ограничен числом 1000).


Pzz>Очевидно, что задача решается с помощью детерминированного регулярного конечного автомата. Следовательно, время обработки входного текста можно сделать вообще не зависящим от количества запрещенных слов, и к тому же весьма быстрым (на каждый входной символ — один раз заглянуть в таблицу).


Построить по запрещённым словам автомат я могу, как после этого найти количество путей в нём, которые не задевали бы терминальные вершины, и при этом имели бы заданную длину N ?

Только что попробовал отработать такую идею. Построим матрицу переходов автомата A, выкинем из неё столбцы и строки, соответствующие терминальным состояниям, затем возведём в степень N. После чего останется просто посчитать сумму элементов A^N, находящихся в столбце корня дерева (root), это и будет число путей длины N из корня (причём не задевающих терминальных состояний, так как мы их предварительно выкинули из матрицы).

Если в автомате будет n = 2000 состояний (крайний случай, число приблизительное, но по порядку оно такое), то сложность возведения матрицы в степень будет n*n*n * log(N) (используем бинарное возведение в степень), при n = 2000 это слишком много (кубическая сложность).

Так что идея с матрицей не проходит...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.