容斥原理在 OI 中的应用

容斥原理

引入

假设班里有 $10$ 个学生喜欢数学,$15$ 个学生喜欢语文,$21$ 个学生喜欢编程,班里至少喜欢一门学科的有多少个学生呢?

第一眼看到这一题,很多人可能直接会想到 $10+15+21=46$ 个学生。然而,这只是一种理想情况。实际生活中,一个人不可能只会喜欢一种。反映到这道题上来说。也许有一部分既喜欢语文又喜欢数学,也许有一部分既喜欢语文又喜欢编程,也许有一部分既喜欢数学又喜欢编程,也许有一部分都喜欢。对于实际情况而言,如果只是简单粗暴地将每一部分的人数加起来,可能就会出现将部分同学算了几次的情况。在出现这种情况时,我们就需要将重复的部分减掉一份。具体地:

解:令集合 $A=\left\{喜欢数学\right\}$。相应地,$B=\left\{喜欢语文\right\}$,$C=\left\{喜欢编程\right\}$。则易知答案为:$$ ans=|A\cup B\cup C|=|A|+|B|+|C|-|A\cap B|-|A\cap C|-|B\cap C| + |A\cap B\cap C| $$ 上式便是容斥原理的一种简单应用。

定义

首先给出容斥原理的一般形式:$$ \begin{aligned} \left|\bigcup_{i=1}^{n}S_i\right|=&\sum_{i}|S_i|-\sum_{i<j}|S_i\cap S_j|+\sum_{i<j<k}|S_i\cap S_j\cap S_k|-\cdots\\ &+(-1)^{m-1}\sum_{a_i<a_{i+1} }\left|\bigcap_{i=1}^{m}S_{a_i}\right|+\cdots+(-1)^{n-1}|S_1\cap\cdots\cap S_n| \end{aligned} $$ 至于证明有两种方式:

  1. 数学归纳法
  2. 考虑每一个数的贡献

这里给出其中一种方式:

证明:当 $n=2$ 时,等式显然成立(证明略)。

假设 $n=s(s\ge 2,s\in \N^+)$ 时结论成立,则当 $n=s+1$ 时:$$ |\bigcup^n_{i=1}A_i|=|\bigcup^{s+1}_{i=1}A_i|=|(\bigcup^s_{i=1}A_i)\cup A_{s+1}| \\ =|\bigcup^s_{i=1}A_i|+|A_{s+1}|-|(\bigcup^s_{i=1}A_i)\cap A_{s+1}| \\ =|\bigcup^s_{i=1}A_i|+|A_{s+1}|-|\bigcup(A_i\cap A_{s+1})| \\ =\sum_{1\le i_1\le s+1}|A_i|+\sum^s_{k=2}(-1)^{k-1}\sum_{1\le i_1<i_2<\cdots <i_k\le s}|A_{i_1}\cap A_{i_2}\cap\cdots\cap A_{i_k}|+ \\ \sum^{s-1}_{k=1}(-1)^k\sum_{1\le i_1<i_2<\cdots<i_k\le s}|A_{i_1}\cap A_{i_2}\cap\cdots\cap A_{i_k}|+ \\ \sum^{s-1}_{k=1}(-1)^k\sum_{1\le i_1<i_2\cdots<i_k\le s}|A_{i_1}\cap A_{i_2}\cap\cdots\cap A_{i_k}\cap A_{i_{s+1}}|+(-1)^s|A_{i_1}\cap A_{i_2}\cap\cdots\cap A_s\cap A_{s+1}| \\ =\sum_{1\le{i_1}\le s+1}|A_i|+[\sum^s_{k=2}(-1)^{k-1}\sum_{1\le i_1<i_2<\cdots <i_k\le s}|A_{i_1}\cap A_{i_2}\cap\cdots\cap A_{i_k}|+ \\ \sum^s_{k=2}(-1)^{k-1}\sum_{1\le i_1<i_2<\cdots <i_{k-1}\le s}|A_{i_1}\cap A_{i_2}\cap\cdots\cap A_{i_{k-1}}\cap A_{i_{s+1}}|]+(-1)^s|A_{i_1}\cap A_{i_2}\cap\cdots\cap A_s\cap A_{s+1}| \\ =\sum_{1\le i_1\le s+1}|A_{i_1}|+\sum^s_{k=2}(-1)^{k-1}\sum_{1\le i_1<i_2<\cdots<i_k\le s+1}|A_{i_1}\cap A_{i_2}\cap\cdots\cap A_{i_k}|+(-1)^s|A_1\cap A_2\cap\cdots\cap A_{s+1}| \\ =\sum^{s+1}_{k=1}(-1)^{k-1}\sum_{1\le i_1<i_2<\cdots<i_k\le s+1}|A_{i_1}\cap A_{i_2}\cap\cdots\cap A_{i_k}| \\ =\sum^{n}_{k=1}(-1)^{k-1}\sum_{1\le i_1<i_2<\cdots<i_k\le n}|A_{i_1}\cap A_{i_2}\cap\cdots\cap A_{i_k}| \\ $$ 所以当 $n=s+1$ 时,结论仍成立。因此对任意 $n\in \N^+,n\ge2$ 均可使所证等式成立。

应用

错排

给定 $n$ 个数,将这 $n$ 个数放入集合 $S$ 中,试求出使得 $\forall i \in [1, n], S_i \ne i$ 的方案数。

递推做法:$$ f_i=\begin{cases} 0, & i=1 \\ (n-1)\times f_{i-1}\times f_{i-2}, & otherwise \\ \end{cases} $$ 直接求解 $f_n$ 即可。

容斥做法:

直接求解错排的个数不是十分方便,我们可以转换一下思路。

很显然:错排个数 = 全排个数 - 不是错排的个数$$ ans=|U|-|\sum^n_{i=1}A_i| \\ =A^n_n-\sum_{i=1}^nA_i+\sum_{1\le i<j\le n}|A_i\cap A_j|-\sum_{1\le i<j<k\le n}|A_i\cap A_j\cap A_k|... $$ 对每一项进行分析:

对于第二项而言,$|A_i|$ 表示第 $i$ 个位置必须是 $i$,而其他位置可以随便搞,依据全排列相关结论可知 $|A_i|=(n-1)!$,则:$$ \sum_{i=1}^nA_i=n\times(n-1)!=\frac{n!}{1!} $$ 对于第三项而言,$|A_i\cap A_j|$ 表示第 $i$ 个位置必须是 $i$ 且第 $j$ 个位置必须是 $j$(注意 $i\ne j$),而其他位置可以随便搞,依据全排列相关结论可知 $|A_i\cap A_j|=(n-2)!$,则:$$ \sum_{1\le i<j\le n}|A_i\cap A_j|=C^2_n(n-2)!=\frac{n!}{2!(n-2)!}(n-2)!=\frac{n!}{2!} $$ 以此类推:$$ \sum_{1\le i<j<k\le n}|A_i\cap A_j\cap A_k|=C^3_n(n-3)!=\frac{n!}{3!(n-3)!}(n-3)!=\frac{n!}{3!} \\ \sum_{1\le i<j<k<l\le n}|A_i\cap A_j\cap A_k\cap A_l|=C^4_n(n-4)!=\frac{n!}{4!(n-4)!}(n-4)!=\frac{n!}{4!} \\ \sum_{1\le i<j<k<l<m\le n}|A_i\cap A_j\cap A_k\cap A_l\cap A_m|=C^5_n(n-5)!=\frac{n!}{5!(n-5)!}(n-5)!=\frac{n!}{5!} \\ ... $$ 最终答案为:$$ ans=|U|-|\sum^n_{i=1}A_i| \\ =A^n_n-\sum_{i=1}^nA_i+\sum_{1\le i<j\le n}|A_i\cap A_j|-\sum_{1\le i<j<k\le n}|A_i\cap A_j\cap A_k|... \\ =A^n_n-\frac{n!}{1!}+\frac{n!}{2!}-\frac{n!}{3!}+\frac{n!}{4!}-\frac{n!}{5!}... \\ =A^n_n-\sum^n_{i=1}(-1)^i\frac{n!}{i!} $$

posted @ 2023-08-29 10:21  tsqtsqtsq  阅读(129)  评论(0)    收藏  举报  来源