补集思想:
正难则反。
将不太好求的满足条件的方案转化成总方案-不合法的方案
容斥原理 :
推荐博客:https://blog.youkuaiyun.com/m0_37286282/article/details/78869512
容斥原理便是补集思想的一部分。
来自度娘的解释:在计数时,必须注意没有重复,没有遗漏。为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理。
也可以这样子描述:
要计算几个集合并集的大小,我们要先将所有单个集合的大小计算出来,然后减去所有两个集合相交的部分,再加回所有三个集合相交的部分,再减去所有四个集合相交的部分,依此类推,一直计算到所有集合相交的部分。
上面的描述可以表示成如下:
它可以写得更简洁一些,我们将B作为所有Ai的集合,那么容斥原理就变成了:
C是B的子集,e是属于C的Ai集合
拓展: minmax容斥
没想到吧,max(S)表示集合S中的最大值,min(S)表示集合S中的最小值
⊆
根据容斥思想有:
max(S)=
∑
T
⊆
S
且
T
!
=
空
集
∑_{T⊆S且T!=空集}
∑T⊆S且T!=空集
(
−
1
)
∣
T
∣
−
1
(-1)^{|T|−1}
(−1)∣T∣−1min(T)
然后期望也可以这样子搞一下:
E(max(S))=
∑
T
⊆
S
且
T
!
=
空
集
∑_{T⊆S且T!=空集}
∑T⊆S且T!=空集
(
−
1
)
∣
T
∣
−
1
(-1)^{|T|−1}
(−1)∣T∣−1E(min(T))
应用例题:有n张卡牌,每秒有pi的概率抽到卡牌i,求至少得到每个卡牌的期望时间。
假设S集合表示每一个卡牌第一次被抽到的时间,那么max(S)可以理解为所有卡牌都被抽到至少一次的时间,min(S)可以理解为第一次抽到卡牌的时间,那么所求的期望时间便是E(max(S))
根据minmax容斥套路公式有:
E
(
m
a
x
(
S
)
)
E(max(S))
E(max(S))=
∑
T
⊆
S
且
T
!
=
空
集
∑_{T⊆S且T!=空集}
∑T⊆S且T!=空集
(
−
1
)
∣
T
∣
−
1
(-1)^{|T|−1}
(−1)∣T∣−1
E
(
m
i
n
(
T
)
)
E(min(T))
E(min(T))
E
(
m
i
n
(
T
)
)
E(min(T))
E(min(T))=
1
∑
i
⊆
T
p
i
1\over{\sum_{i⊆T}pi}
∑i⊆Tpi1
【有
∑
i
⊆
T
p
i
\sum_{i⊆T}pi
∑i⊆Tpi的概率成功,期望便是倒数】
然后枚举子集累计贡献。
然后大多数题目能用minmax容斥的话基本套路是不变的,主要是如何表示出E(min(T)),这是关键。
心得:容斥原理就是因为反过来更加容易统计,所以考虑反过来的情况。
get小技巧:容斥原理中的枚举子集,应该怎么样有序,不重不漏的枚举呢?
位运算方法:设集合长度为len,那么我们用一个长为len的二进制数来表示每一个子集,若第i位为1则表示第i个元素被选入子集中。
code
for(int i=1;i<(1<<len);i++) //若考虑空集i从0开始
for(int j=0;j<len;j++)
if(i&(1<<j)) //第j+1个元素被选进子集中
....//计算当前子集的贡献
每一个i表示一个二进制数,表示一个子集的状态,由于二进制位是从0~len-1,我们j的枚举也是0 ~ len-1
一般来说:枚举子集时,若子集是奇数的就累计答案,偶数的就减。
容斥原理的基础部分应该还好,但是将其题目与组合数学结合起来我真的一头雾水,理解思想是关键,活用公式模板,寻找合适的容斥方案,在结合一些数学知识以及神奇优化…赶紧填坑去!