从n个人选m个。如果不考虑顺序,那么方案数就是({n} choose {m}),也可以表示为(C_n^m),这个数学式子叫做组合数,也叫作二项式系数(因为存在二项式定理)。如果考虑顺序,那么方案数就是(A_n^m),A也可以换成P,这个叫做排列数。
计算式
[ A_n^m=n(n-1)(n-2)cdots(n-m+1)=frac{n!}{(n-m)!} \
C_n^m=frac{n!}{m!(n-m)!}
]
排列数的理解:第一次有n人可选,第二次有(n-1)人可选···最后有(n-m+1)人可选。m个人全排列的方案数就是m!组合数不考虑顺序,就除去。
特殊定义 若n>m 那么这些数的值就是0,n=m,值就是1,m=0,值也还是1。
组合数比较重要,介绍几个组合数的性质
[inom{n}{m}=inom{n}{n-m}
]
证明
从n个选m个,等价于从n个选出n-m个。这两种选取的方式一一对应,分别构成两个集合,这两个集合大小一样。
证毕
[inom{n}{m}=inom{n-1}{m}+inom{n-1}{m-1}
]
证明:(杨辉三角形直接证明)
从n个选m个有两种办法:
1.先选n号,剩下n-1个选m-1个
2.不选n号,剩下n-1个选m个
证毕
[ inom{n}{0}+inom{n}{1}+inom{n}{2}+cdots+inom{n}{n}=2^n
]
证明:
从n个选若干个,有n+1种办法(0个,1个···n+1个)。换个角度,每个物品有选或不选两个选项,那么共有(2^n)种方案
证毕
组合数求法:
1.O(n^2)
c[0][0]=1;
for(register int i(1);i<=n;++i)
{
c[i][0]=c[i][i]=1;
for(register int j=1;j<i;++j){
c[i][j]=c[i-1][j]+c[i-1][j-1];
}
}
2.求某个组合数,可以O(n)求,要求预处理阶乘
inline void calc() {
fac[0] = 1;//¹æ¶¨0!=1
int t=MX-5;
rep(i, 1, t)
fac[i] = (fac[i - 1] * i) % mod;
inv_fac[t] = Fermat_inv(fac[t], mod);
drp(i, t-1, 0)
inv_fac[i] = inv_fac[i + 1] * (i + 1) % mod;
}
inline lxl C(lxl r,lxl n){
if(n==0) return 1;
return fac[n]*inv_fac[r]%mod*inv_fac[n-r]%mod;
}
3.若n,m是高精度数字,为了避免除法(除法太慢了。。还有逆元的问题。。)我们可以把阶乘进行质因子分解。把分子质因数的指数减去分母的质因数,可以证明分母可以完全被消去。最后把质因子相乘就可。时间复杂度O(n log n)
可见acwing888,没做过。。没法给模板,大家自己百度查题解吧。
二项式定理
[(a+b)^n=sum_{i=0}^{n} inom {n}{i}a^{i}b^{n-i}
]
证明: (只会数学归纳法)
[当n=1,(a+b)^1= inom{1}{0}ab^0+inom{0}{1} a^0 b=a+b\
假设当n=m时成立,那么将该式推向n=m+1\
egin{align}
(a+b)^{m+1} &=(a+b)(a+b)^m \
&=(a+b)sum_{i=0}^{m} inom {m}{i}a^{i}b^{m-i} \
&= sum_{i=0}^{m} inom {m}{i}a^{i+1}b^{m-i} +sum_{i=0}^{m} inom {m}{i}a^{i}b^{m-i+1} \
&=sum_{i=1}^{m+1} inom {m}{i}a^{i}b^{m-i+1} +sum_{i=0}^{m} inom {m}{i}a^{i}b^{m-i+1} \
&=sum_{i=0}^{m+1} [inom {m}{i-1}+ inom{m}{i}] a^{i}b^{m-i+1} \
&=sum_{i=0}^{m+1} inom{m+1}{i} a^{i}b^{m+1-i}
end{align}
]
证毕