公式
- 普通阶乘
Dn=|I|−n∑i=1|Si|+n∑i=1∑j>i|Si∩Sj|−n∑i=1∑j>i∑k>i|Si∩Sj∩Sk|+…+(−1)n−1|S1∩S2∩…∩Sn|
=n!(1−11!+12!−13!+…+(−1)n1n!)
- 递推关系
Dn=(n−1)(Dn−1+Dn−2),D1=0,D2=1
Dn=nDn−1+(−1)n
三种生成方式
递归
时间复杂度为O(Dn),但是由于递归函数的调用开销是很大的,系统要为每次函数调用分配存储空间,并将调用点压栈予以记录。而在函数调用结束后,还要释放空间,弹栈恢复断点。所以,考虑函数处理过程,整体看来,递归法的效率并不高。
1 | void Digui(int n,int cur,int vis[]) //递归 |
字典序生成法
用全排列的字典序生成法,同时对每次生成的全排列检验是否合法。
时间复杂度O(2n∗n!)
1 | void Dictionary(int n) //字典生成 |
改进的字典序生成法
在对于某一个生成的全排列时判断,同时对接下来不正确的全排列都跳过。由于这种额外的判断方式,我们不能再使用next_permutation函数。
时间复杂度O(Dn)
1 | int AdLxOrder(int n) |