容斥原理的公式推导
2018-03-28 16:09
417 查看
对于容斥原理的最简单的理解就是,把要计算的加上,然后把加多的减掉,然后再把减多的再加回去。这样循环下去就对了。
一个好理解的例子就是一个班上有三个兴趣班(c++,java,pasico),每个人都报了兴趣班。30人报了一个,12人报了两个,3人报了三个,求班上有多少人?这是一道小学题,自然也很简单。ans=30-12+3=21(人)。然后这样为什么是对的呢?我们思考一下30之中把报了两项的人计算了2次,把报了三项的人计算了3次。12中把报了3项的人计算了3次。所以我们用那个加减表示每种人都只计算1次的答案。(可以看图再理解一下)
但是并没有那么简单,因为不可能每道题的系数都是-1和1的交替。要解决更一般性的问题,我们可能要自己推系数,我们重点讲一下推系数的方法。
一般的,由总结的公式得出∑ni=1s(Ci)fi=s(C0)∑i=1ns(Ci)fi=s(C0),其中s(Ci)s(Ci)表示所有物品在满足CiCi情况下的总贡献(一般的计数问题s(Ci)s(Ci) 就是 满足条件CiCi 情况的个数),而fifi是一个系数,在计算时,我们才能把除答案以外的的贡献消掉。(这是用于计算答案的式子)要对这个公式有一个理解,我们还是举两个例子。
一、(错排问题),一串1−n1−n的数列,求对于任意ii不在第ii位排列的方案数。
对于这个问题,首先我们要构造CiCi,当然这是很简单的,我们很容易就可以想到:CiCi表示满足有至少ii个不错排数的情况。所以有:∑ni=0Cin∗fi==[n==0]∑i=0nCni∗fi==[n==0]。反正第一次看人家推这个式子是懵逼的,为啥s(Ci)s(Ci)变成一个组合数了呢?其实仔细推敲一下还是可以理解的。首先,上面的式子和下面是有区别的。也就是说,这俩货都不是一个东西。这个式子是用来计算fifi的!!!
现在大概能懂了吧,假设有一个恰好有nn个不错排数的情况,它在i=0i=0时被计算了C0nCn0次,在i=1i=1时被计算了C1nCn1次,以此类推……因为我们要求的的是错排数列,所以当n≠0n≠0时是不符合题意的,我们要让它的贡献为0(另:只有n=0n=0时,这个排列的贡献为1)。然后可以想到一个n2n2递推fifi的方法。当然这类fifi是有规律的,我们打表可知:fi=(−1)ifi=(−1)i。
至此我们把fifi全部计算出来了,之后我们怎么计算答案呢?这个时候我们就可以使用上面一个公式了。ans=∑ni=1Cin∗(n−i)!∗fians=∑i=1nCni∗(n−i)!∗fi。
是不是很神奇呢?
二、(约数问题),给定mm个数,统计在[1,n][1,n]中,有奇数个整除它的数的个数。(ii属于[1,n][1,n],若在这mm个数里,有奇数个数可以整除ii,则ansans++),m≤15m≤15,n≤1e9n≤1e9。
枚举nn的复杂度是n∗mn∗m的,显然会超时,考虑容斥。
枚举mm的子集,求lcmlcm,有了第一题的经验,我们写出式子:∑ki=0Cin∗fi=[k%2==1]∑i=0kCni∗fi=[k%2==1],(奇数时贡献为1)。对于一个约数恰好为kk个的数,它在计算至少0个约数的时候计算了C0kCk0次,在计算至少1个约数时计算了C1kCk1次,以此类推……
怎么计算答案呢?ans=∑(s∈m)nlcm(s)∗f|s|ans=∑(s∈m)nlcm(s)∗f|s|。
其实看懂了也很简单,一般求fifi的式子含组合数,当然也有可能是一些奇奇怪怪的东西,比如斯特林数什么的。
一个好理解的例子就是一个班上有三个兴趣班(c++,java,pasico),每个人都报了兴趣班。30人报了一个,12人报了两个,3人报了三个,求班上有多少人?这是一道小学题,自然也很简单。ans=30-12+3=21(人)。然后这样为什么是对的呢?我们思考一下30之中把报了两项的人计算了2次,把报了三项的人计算了3次。12中把报了3项的人计算了3次。所以我们用那个加减表示每种人都只计算1次的答案。(可以看图再理解一下)
但是并没有那么简单,因为不可能每道题的系数都是-1和1的交替。要解决更一般性的问题,我们可能要自己推系数,我们重点讲一下推系数的方法。
一般的,由总结的公式得出∑ni=1s(Ci)fi=s(C0)∑i=1ns(Ci)fi=s(C0),其中s(Ci)s(Ci)表示所有物品在满足CiCi情况下的总贡献(一般的计数问题s(Ci)s(Ci) 就是 满足条件CiCi 情况的个数),而fifi是一个系数,在计算时,我们才能把除答案以外的的贡献消掉。(这是用于计算答案的式子)要对这个公式有一个理解,我们还是举两个例子。
一、(错排问题),一串1−n1−n的数列,求对于任意ii不在第ii位排列的方案数。
对于这个问题,首先我们要构造CiCi,当然这是很简单的,我们很容易就可以想到:CiCi表示满足有至少ii个不错排数的情况。所以有:∑ni=0Cin∗fi==[n==0]∑i=0nCni∗fi==[n==0]。反正第一次看人家推这个式子是懵逼的,为啥s(Ci)s(Ci)变成一个组合数了呢?其实仔细推敲一下还是可以理解的。首先,上面的式子和下面是有区别的。也就是说,这俩货都不是一个东西。这个式子是用来计算fifi的!!!
现在大概能懂了吧,假设有一个恰好有nn个不错排数的情况,它在i=0i=0时被计算了C0nCn0次,在i=1i=1时被计算了C1nCn1次,以此类推……因为我们要求的的是错排数列,所以当n≠0n≠0时是不符合题意的,我们要让它的贡献为0(另:只有n=0n=0时,这个排列的贡献为1)。然后可以想到一个n2n2递推fifi的方法。当然这类fifi是有规律的,我们打表可知:fi=(−1)ifi=(−1)i。
至此我们把fifi全部计算出来了,之后我们怎么计算答案呢?这个时候我们就可以使用上面一个公式了。ans=∑ni=1Cin∗(n−i)!∗fians=∑i=1nCni∗(n−i)!∗fi。
是不是很神奇呢?
二、(约数问题),给定mm个数,统计在[1,n][1,n]中,有奇数个整除它的数的个数。(ii属于[1,n][1,n],若在这mm个数里,有奇数个数可以整除ii,则ansans++),m≤15m≤15,n≤1e9n≤1e9。
枚举nn的复杂度是n∗mn∗m的,显然会超时,考虑容斥。
枚举mm的子集,求lcmlcm,有了第一题的经验,我们写出式子:∑ki=0Cin∗fi=[k%2==1]∑i=0kCni∗fi=[k%2==1],(奇数时贡献为1)。对于一个约数恰好为kk个的数,它在计算至少0个约数的时候计算了C0kCk0次,在计算至少1个约数时计算了C1kCk1次,以此类推……
怎么计算答案呢?ans=∑(s∈m)nlcm(s)∗f|s|ans=∑(s∈m)nlcm(s)∗f|s|。
其实看懂了也很简单,一般求fifi的式子含组合数,当然也有可能是一些奇奇怪怪的东西,比如斯特林数什么的。
相关文章推荐
- 深度学习算法之CNN、RNN、LSTM公式推导
- 概率论 --- 对于全错位排列概率公式的证明推导
- 机器学习19-SVM线性可分公式推导(一)
- vijos - P1543极值问题(斐波那契数列 + 公式推导 + python)
- 反向传播算法的公式推导(BP算法)
- RNN网络结构及公式推导
- 线性可分支持向量机思想与公式推导
- 对数变换公式的推导
- 3阶差分方程在有重根下的一般计算公式的推导
- HDU/HDOJ 3524 公式推导 2010年多校联合第九场
- hdu 5584 LCM Walk(数学推导公式,规律)
- HDU 2298 Toxophily(公式推导)
- 需求定律公式和需求弹性推导——《可…
- 机器学习SVM之SMO方法α,ω和b迭代公式的推导过程
- 推导平行四边形面积公式教学课件模板免费下载
- 027 反三角函数的求导公式推导
- [HDU]4035 Maze 期望公式推导
- [小白式机器学习(一)] logistic regression(LR)对数几率回归 / 逻辑回归 公式推导
- 关于已知两点经纬度求球面最短距离的公式推导
- bzoj 1426(期望dp)(公式推导)