Всякий раз, когда я делаю что-либо, что связано с большим количеством перестановок, я думаю о том, как можно избежать повторного вычисления значений, которые я уже вычислил, при генерации перестановок. Одним из таких подходов является использование рекурсии. Используя рекурсию, вы часто можете вычислить первые n возможностей один раз и передать вычисленное значение вперед всем остальным вызовам функций, не пересчитывая его n! раз. Затем следующий вызов функции обрабатывает n-1 возможностей и так далее. Проблема этого подхода заключается в том, что рекурсия сама по себе может добавить довольно большие накладные расходы ко всем вызовам функций и не позволяет компилятору встраивать + применять дальнейшие оптимизации.
Учитывая, что вы говорите, у вас есть n! Перестановки, я бы предположил, что вы, вероятно, переставляет n предметов. Если для создания каждой перестановки требуется некоторое время (это не просто сложение / умножение или что-то в этом роде), вы могли бы подумать о том, чтобы (если возможно) сгенерировать все возможные перестановки k-элементов, то есть k! * (20 выбирают k), все еще намного меньше, чем 20! для малых к. Затем сохраните это в чем-то вроде хеш-таблицы или отсортированного массива, а затем найдите соответствующие значения для всех остальных (20-k)! * (20 выберите k) перестановок. Если вы ищете какое-то оптимальное значение, попробуйте «вычесть» это из каждого запроса в таблицу поиска (снова, если это возможно), если есть запись, то для оптимального значения.
Боюсь, что без дальнейших подробностей о проблеме я не могу предложить больше.