组合数学基础知识,整理所学
一. 组合数递推公式:
??_??^??=??_(???1)^(???1)+??_(???1)^??
C(n,m) = C(n-1,m)+C(n-1,m-1);
二. 鸽笼原理
描述:
如果n个物体被放进m个盒子,那么至少有一个盒子有???/???个物体。 -->意思为向上取整,用floor函数可以实现
经典案例:
对数列a1,a2,a3,……an,至少存在1≤i<j≤n,使得∑1_(??=??)^?? ??_?? 能被n整除。 -->即ai+..+aj 能被n整除。
证明如下:
作和函数 S1 = a1;S2 = a1+a2... ;Sn = a1+a2+a3+..+an; 假设这n个数不能被n整除,则余数的域为1--n-1,
这就相当于把n-1个数放进n个笼子,肯定有两个余数相等,则肯定有Sj - Si 能被n整除。
三. 容斥原理
几个集合并集的大小=所有单个集合的大小之和-(所有任意)两个的交+(所有任意)三个的交-(所有任意)四个的交……
比如??∪??∪?? = ??+??+?????∩?????∩?????∩??+??∩??∩??。
四. 母函数 --生成函数
在数学中,某个序列的母函数(Generating function,又称生成函数)是一种形式幂级数
其每一项的系数可以提供关于这个序列的信息。使用母函数解决问题的方法称为母函数方法。
普通型母函数
举个例子:
若有1克、2克、3克、4克的砝码各一枚,能称出哪几种重量?各有几种可能方案?
现在x的指数表示称出的重量。
1个1克的砝码可以用函数1+1*x^1表示,
1个2克的砝码可以用函数1+1*x^2表示, //如果有3个2g的砝码呢? 表示为 1+x^2+x^4+x^6
1个3克的砝码可以用函数1+1*x^3表示,
1个4克的砝码可以用函数1+1*x^4表示,
我们拿1+x^2来说,前面已经说过,x表示砝码,x的指数表示砝码的重量!初始状态时,这里就是一个质量为2的砝码。
那么前面的1表示什么?按照上面的理解,1其实应该写为:1*x^0,即1代表重量为2的砝码数量为0个。
所以这里1+1*x^2 = 1*x^0 + 1*x^2,即表示2克的砝码有两种状态,不取或取,不取则为1*x^0,取则为1*x^2
接下来我们把他们乘起来(1+??)*(1+??^2)*(1+??^3)*(1+??^4=1+??+??^2+〖2??〗^3+2??^4+2??^5+2??^6+2??^7+??^8+??^9+??^10
指数即拿的重量,系数就是对应的方案数(zhen tm niu bai)
五. 母函数模板:
存多项式。使用数组维护的。下标是多项式的指数,存的是该项的系数!
1 //注意所有操作是从下标为0开始的! a[0]就是 1的系数,也就是常数项 2 3 #include<iostream> 4 5 using namespace std; 6 7 int a[1000],b[1000];//a存多项式,下标是指数,存的是系数! b是中间的,存每一次的结果! 8 9 int v[100],num[100]; //硬币面值,个数 10 11 int n; //n是硬币种类数 12 13 void GFunction(){ 14 15 for(int i= 0;i<=num[0]*v[0];i++) a[i] = 1; //初始化, 16 17 int lastindex = num[0]*v[0]; //记录目前最大的多项式指数 18 19 for(int i = 1;i<n;i++){ 20 21 for(int j = 0;j<=lastindex;j++){ 22 23 for(int k = 0;k<=num[i]*v[i];k+=v[i]){ 24 25 b[j+k] += a[j]; 26 27 } 28 29 } 30 31 lastindex += num[i]*v[i]; 32 33 for(int j = 0;j<=lastindex;j++){ 34 35 a[j] = b[j]; 36 37 b[j] = 0; 38 39 } 40 41 } 42 43 return; 44 45 } 46 47 48 //测试 49 50 int main(){ 51 52 v[0] = 1,v[1] = 2,v[2] =3,v[3] = 4; 53 54 n =4; 55 56 for(int i =0 ;i<4;i++){ 57 58 num[i] = 1; 59 60 } 61 62 GFunction(); 63 64 for(int i = 0;i<=10;i++){ 65 66 cout<<a[i]<<endl; 67 68 } 69 70 }
令:指数型母函数:
解决多重集合的排列问题。
写母函数的时候,默认系数不是1,而是1/"对应幂次的阶乘 "
乘积对应系数分母保持不变,此时分子是排列数。
七. 错排数
十本不同的书放在书架上。现重新摆放,使每本书都不在原来放的位置。有几种摆法?
通项公式:D(??)=??!*( 1/2! ? 1/3! +…+ (?1)^?? *1/??!)
近似公式:D(??)=???!/??+0.5? 此为i/e + 0.5 向下取整!
递推公式:D(??)=(???1)*(??(???1)+??(???2))
应用:n个元素的排列都不在自己原有位置上的方案数;
八. 卡特兰数
通项公式:?(??)=C(2n,n) - C(2n,n-1)
递推公式:?(??)=h(???1) *(4???2)/(??+1)
前几项为1, 1, 2, 5, 14, 42, 132……(从h(0)开始)
应用:n个结点能构成h(n)种不同的二叉树;
按1、2……n的次序进栈,有h(n)种不同出栈序列;
n对小括号进行有效匹配的方案数为h(n)……
九. 二项式定理深入理解
〖(??+??)〗^??=??^??+??_??^1 ??^(???1) ??+??_??^2 ??^(???2) ??^2+…+??_??^(???2) ??^2 ??^(???2)+??_??^(???1) ??^1 ??^(???1)+??^??
理解:
有n项(a+b)相乘,我从这里面找a的n次方系数,就是n项都选a,这有一种法;
如果找 a的n-2*b的2 系数,就是n个式子选两个2,有C(n,2)种法。
算法持续更新,以上。