洛谷P1595 信封问题 题解 二项式反演
题目链接:https://www.luogu.com.cn/problem/P1595
设
- \(f_n\) 表示 恰好 装错 \(n\) 封信的方案数;
- \(g_n\) 表示 装错 \(\le n\) 封信的方案数。
则
\[g_n = \sum_{i=0}^n f_i
\]
根据 二项式反演 得
\[f_n = \sum_{i=0}^n \binom{n}{i} (-1)^{n-i} g_n
\]
而本题中 \(g_n\) 就是 \(n\) 个数的全排列,即 \(g_n = n!\),所以
\[f_n = \sum_{i=0}^n \binom{n}{i} (-1)^{n-i} n!
\]
示例程序:
#include <bits/stdc++.h>
using namespace std;
long long fac[22] = {1}, flag[22] = {1}, c[22][22], ans;
int n;
void init(int n) {
for (int i = 1; i <= n; i++)
flag[i] = -flag[i-1], fac[i] = fac[i-1] * i;
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= i; j++) {
if (j == 0 || j == i)
c[i][j] = 1;
else
c[i][j] = c[i-1][j-1] + c[i-1][j];
}
}
}
int main() {
cin >> n;
init(n);
for (int i = 0; i <= n; i++)
ans += c[n][i] * flag[n-i] * fac[i];
cout << ans << endl;
return 0;
}
浙公网安备 33010602011771号