Посчитать количество перестановок n элементов без неподвижных точек (дерангементы) можно разными способами; сравните применение формулы включений-исключений, рекуррентных соотношений и приближений (например, n!/e), оцените точность и удобство для больших n
Коротко — три подхода, точность и удобство. 1) Формула включений‑исключений (точно) !n=n!∑k=0n(−1)kk! !n = n!\sum_{k=0}^n \frac{(-1)^k}{k!} !n=n!∑k=0nk!(−1)k. Плюсы: даёт точное значение и очевидное доказательство. Минусы: при вычислениях в плавающей точке сильная вычитательная потеря точности из‑за чередующихся больших членов; надо либо работать с целыми (через факториалы) либо с высокой точностью. Вычислительная сложность — O(n)O(n)O(n) операций. 2) Рекуррентное соотношение (практично для точных значений) !0=1, !1=0, !n=(n−1)(!(n−1)+!(n−2)) !0=1,\; !1=0,\; !n=(n-1)(!(n-1)+!(n-2))!0=1,!1=0,!n=(n−1)(!(n−1)+!(n−2)). Плюсы: простой, стабильный, требует O(n)O(n)O(n) целочисленных умножений/сложений, мало памяти (хранить последние два значения). Лучший выбор для получения точного !n!n!n для больших nnn с использованием больших целых (bigint). Минусы: значением растёт как n!n!n!, поэтому требуется память/время для работы со многозначными целыми при очень больших nnn. 3) Приближение (очень удобно для оценок) Основное приближение !n∼n!e !n \sim \frac{n!}{e} !n∼en!, и более точно !n=⌊n!e+12⌋ !n = \left\lfloor\frac{n!}{e}+\tfrac12\right\rfloor!n=⌊en!+21⌋ (для n≥1n\ge1n≥1). Абсолютная погрешность оценена так: ∣ !n−n!e ∣≤1n+1\displaystyle |\,!n-\frac{n!}{e}\,| \le \frac{1}{n+1}∣!n−en!∣≤n+11, поэтому для умеренно больших nnn абсолютная ошибка крайне мала; относительная ошибка ещё меньше (поскольку n!/en!/en!/e огромно). Для грубой оценки можно также использовать формулу Стирлинга для n!n!n!. Рекомендация - Если нужен точный результат для большого nnn: использовать рекурренту и big integers. - Если нужна быстрая оценка или порядок величины: взять n!e\frac{n!}{e}en! (или Стирлинг для логарифма), и при необходимости округлить по формуле выше (даёт точное значение для большинства nnn). - Формула включений полезна теоретически и для вывода оценок, но для численных вычислений уступает рекурренте по устойчивости.
1) Формула включений‑исключений (точно)
!n=n!∑k=0n(−1)kk! !n = n!\sum_{k=0}^n \frac{(-1)^k}{k!} !n=n!∑k=0n k!(−1)k .
Плюсы: даёт точное значение и очевидное доказательство. Минусы: при вычислениях в плавающей точке сильная вычитательная потеря точности из‑за чередующихся больших членов; надо либо работать с целыми (через факториалы) либо с высокой точностью. Вычислительная сложность — O(n)O(n)O(n) операций.
2) Рекуррентное соотношение (практично для точных значений)
!0=1, !1=0, !n=(n−1)(!(n−1)+!(n−2)) !0=1,\; !1=0,\; !n=(n-1)(!(n-1)+!(n-2))!0=1,!1=0,!n=(n−1)(!(n−1)+!(n−2)).
Плюсы: простой, стабильный, требует O(n)O(n)O(n) целочисленных умножений/сложений, мало памяти (хранить последние два значения). Лучший выбор для получения точного !n!n!n для больших nnn с использованием больших целых (bigint). Минусы: значением растёт как n!n!n!, поэтому требуется память/время для работы со многозначными целыми при очень больших nnn.
3) Приближение (очень удобно для оценок)
Основное приближение
!n∼n!e !n \sim \frac{n!}{e} !n∼en! ,
и более точно
!n=⌊n!e+12⌋ !n = \left\lfloor\frac{n!}{e}+\tfrac12\right\rfloor!n=⌊en! +21 ⌋ (для n≥1n\ge1n≥1).
Абсолютная погрешность оценена так:
∣ !n−n!e ∣≤1n+1\displaystyle |\,!n-\frac{n!}{e}\,| \le \frac{1}{n+1}∣!n−en! ∣≤n+11 ,
поэтому для умеренно больших nnn абсолютная ошибка крайне мала; относительная ошибка ещё меньше (поскольку n!/en!/en!/e огромно). Для грубой оценки можно также использовать формулу Стирлинга для n!n!n!.
Рекомендация
- Если нужен точный результат для большого nnn: использовать рекурренту и big integers.
- Если нужна быстрая оценка или порядок величины: взять n!e\frac{n!}{e}en! (или Стирлинг для логарифма), и при необходимости округлить по формуле выше (даёт точное значение для большинства nnn).
- Формула включений полезна теоретически и для вывода оценок, но для численных вычислений уступает рекурренте по устойчивости.