组合数学学习笔记
我会说这是个坑吗
蒟蒻开始学组合数学了……
尽管我在认真,刷题速度和学习进度还是要被大佬们甩好几条街……
忙着刷题后期肯定没办法写总结,
就只好一边学习一边填坑啦啦啦。
^上面的都是废话^
一、什么是组合数学(完全没用,建议跳)
对于很多计数类问题,
由于方案数过于巨大,
我们无法用搜索的方式来解决问题
因此我们需要对计数类问题进行一些优化
这些优化就是组合数学研究的内容
:(没错就是研究计数类问题)
二、基本原理
加法原理:如果完成一件事有两类方法,第一类方法有m1种方案,第二类方法有m2种方案,那么完成这件事有m1+m2种方案 将方案分类,类类相加,并且要不重不漏
乘法原理:如果完成一件事有两步,第一步有m1种方案,第二步方法有m2种方案,那么完成这件事有m1*m2种方案 将方案分步,步步相乘 。
(这两种原理都好说,稍加理解立即明白,以下的知识几乎都要基于这两种原理咕~)
三、排列与组合
:(弱小的主角)
排列:从n个不同的元素中取出m(m≤n)个元素,按照一定的顺序排成一列,叫做从n个不同元素中取出m个元素的一个排列
从n个数中取出m个数进行排列的方案数用符号A(n,m)表示
公式:A(n,m)=n*(n-1)*(n-2)*...*(n-m+1)=n!/(n-m)!
(自己理解:第一个数字有n种选择,第二个数字有(n-1)中选择,以此类推,然后相乘)
组合:从n个不同元素中取出m(m≤n)个元素的所有组合的个数,叫做从n个不同元素中取出m个元素的组合数 从n个数中取出m个数的方案数用符号C(n,m)表示
公式:C(n,m)=A(n,m)/A(m,m)=n!/(m!(n-m)!)
(自己理解:每一种组合有A(m,m)种排列,所以每一种组合被这A(m,m)中排列算重了A(m,m)次,除掉就好啦)
四、定理一箩筐(这东西才是组合数学(死亡)的真谛啊)
欧几里得算法:
这东西好说。辗转相除法。
一个式子基本上就涵盖了:gcd(a,b)=gcd(b,a%b);
事实上里面还有一点东西,就是和更相减损术一起用来优化(我不知道我理解的对不对啊QAQ)
1.若x,y均为偶数,则gcd(x,y)=2*gcd(x/2,y/2);
2.若x为偶数,y为奇数,则gcd(x,y)=gcd(x/2,y);
3.若x为奇数,y为偶数,则gcd(x,y)=gcd(x,y/2);
4.若x,y均为奇数,则gcd(x,y)=gcd(x-y,y);
——《信息学奥赛之数学一本通》
代码不放啦~
懒的理直气壮
扩展欧几里得算法:
蒟蒻我花了半个小时看了证明!(傻得无所畏惧,证明一共不到三行)
然后自己推了三遍终于烂熟于胸……(不仅傻,而且笨……)
下面给出证明(保证默写拒不翻书如有错误请大佬指正)
解丢番图方程:ax+by=c
我们先解ax+by=gcd(a,b);
(跟据裴蜀定理,ax+by=c仅当gcd(a,b)|c时有整数解)
ax+by=gcd(a,b)=gcd(b,a%b)=b*x+a%b*y=b*x+(a-a/b*b)*y=b*x+a*y-a/b*b*y=a*y+(x-a/b*y)*b
完。(注意上面用到的除都是整除啊~:5/2=2)
啥?你没看懂?不要紧我们把其中的两个式子提出来看!
ax+by=gcd(a,b)=gcd(b,a%b)=b*x+a%b*y=b*x+(a-a/b*b)*y=b*x+a*y-a/b*b*y=a*y+(x-a/b*y)*b
这两个式子是等价的!
所以我们得到回溯关系:x=y,y=x-a/b*y。
及:在递归求gcd中,回溯时x=y,y=x-a/b*y。
就是这样啦啦啦~
inline int exgcd(int a,int b,int &x,int &y) { if(b==0) { x=1,y=0; return a; } int d=exgcd(b,a%b,x,y); int tmp=x; x=y; y=tmp-a/b*y; return d; }
Lucas定理(蒟蒻尝试着看证明结果被洗礼了……)
Lucas是用来求C(n,m)%p的方法,时间复杂度挺低的,不过要求p为质数。
给出式子:C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)%p
然后就递归下去。
递推式:Lucas(n,m)%p=Lucas(n/p,m/p)*C(n%p,m%p)%p
好说,递归啊~
边界显然是m=0,return 1;
代码回头再放~(懒~)
蒟蒻赶紧继续去看证明……
所以有了Lucas我们就可以写下面这道题了:
「集合计数」
题目描述:从n个数的数列中取出若干个集合,要求这些集合的交集一共有k个元素,求取数方案个数。
题解:我们先取出来k个数,让剩下的数集合交集为空集就好啦~
撕烤一下,直接让他们交集为空集好像不好实现。
剩下的n-k个数总共会组成2n-k个集合。这2n-k个集合取或不取又能组成22n-k种取集合的方案。
所以我们枚举交集元素为k到n,容斥就好啦~
五、基本数学方法:(转自PPT)
一、特殊元素和特殊位置优先策略(有时需要注意分情况)
由0,1,2,3,4,5可以组成多少个没有重复数字的五位奇数
解:由于末位和首位有特殊要求,
应该优先安排,
以免不合要求的元素占了这两个位置。
先排末位共有C(3,1),然后排首位共有C(4,1),最后排其它位置共有A(4,3)
由分步计数原理得C(3,1)C(4,1)A(4,3)
二、相邻元素捆绑策略(不要忽略捆绑元素内部排列!)
7人站成一排 ,其中甲乙相邻且丙丁相邻,共有多少种不同的排法.
解:先将甲乙两元素捆绑成整体并看成一个复合元素,
同时丙丁也看成一个复合元素,
再与其它元素进行排列,
同时对相邻元素内部进行自排。
由分步计数原理可得共有A(5,5)A(2,2)A(2,2)种不同的排法。
三、不相邻问题插空策略(注意特殊情况:详见题解[排队])
一个晚会的节目有4个舞蹈,2个相声,3个独唱,舞蹈节目不能连续出场,则节目的出场顺序有多少种?
解:分两步进行 第一步,排列2个相声和3个独唱,共有A(5,5)种方案
第二步,将四种舞蹈插入第一步排好的5个元素中间包含首尾两个空位A(6,4)共有种不同的方法,
节目的不同顺序共有A(5,5)A(6,4)种。
四、定序问题倍缩空位插入策略
7人排队,其中甲乙丙3人顺序一定,共有多少不同的排法 (倍缩法)
对于某几个元素顺序一定的排列问题,
可先把这几个元素与其他元素一起进行排列,
然后用总排列数除以这几个元素之间的全排列数,
则共有不同排法种数是A(7,7)/A(3,3)
五、排列问题求幂策略
把6名实习生分配到7个车间实习,共有多少种不同的分法
解:完成此事共分六步:
把第一名实习生分配到车间有7种分法,
把第二名实习生分配到车间也有7种分法
依此类推,
由乘法原理共有7^6种不同的排法。
六、环排问题转化成线排策略
8人围桌而坐,共有多少种坐法?
解:围桌而坐与坐成一排的不同点在于,
坐成圆形没有首尾之分,
所以固定一人,并从此位置把圆形展成直线其余7人共有(8-1)!=7!种排法
七、多排问题转化成直排策略
8人排成前后两排,每排4人,其中甲乙在前排,丙在后排,共有多少排法
8人排前后两排,相当于8人坐8把椅子,
可以把椅子排成一排。
前排有2个特殊元素,
方案数为A(4,2) 后4个位置上有一个特殊元素丙,
方案数为A(4,1) 其余的5人在5个位置上任意排列,
方案数为A(5,5) 共有A(4,2)A(4,1)A(5,5)种方案
八、排列组合混合问题先选后排策略
有5个不同的小球,装入4个不同的盒内,每盒至少装一个球,求共有多少不同的装法
第一步从5个球中选出2个组成复合元共有C(5,2)种方法.
再把4个元素(包含一个复合元素)装入4个不同的盒内有A(4,4)种方法
根据分步计数原理装球的方法共有C(5,2)A(4,4)。
九、平均分组问题除法策略
6本不同的书平均分成3堆,每堆2本共有多少分法
分三步取书得C(6,2)C(4,2)C(2,2)种方法,
但这里出现重复计数的现象
每种方案计算了A(3,3)次,
故最终答案为C(6,2)C(4,2)C(2,2)/A(3,3)
十、重排列
由四面红旗,三面蓝旗,二面黄旗,五面绿旗排成的一排彩旗有多少种?
将14面彩旗排成一个排列,方案数A(14,14) 其中红旗之间每种排列等价,
方案数A(4,4) A(14,14)/(A(4,4)A(3,3)A(2,2)A(5,5))
六、求逆元(求组合数要用逆元QAQ)
求逆元是一个痛苦的回忆……
不仅贼难求而且不同情况下用于求逆元的方法还不一样……
坑
0x7fffffff:简单的组合问题(蒟蒻我在认真推式子QAQ~)
T1:记者要为5名志愿者和他们帮助的2位老人拍照,要求排成一排,2位老人相邻但不排在两端,求不同排法的数量。
解:两名老人捆绑(怪怪的……我不是坏人QAQ),
五名志愿者排列A(5,5),两名老人排列A(2,2),
将两名老人的整体插入到4个空隙中A(4,1)(不能在两边)。
960。
T2:用0到9这10个数字,可以组成多少个没有重复数字的三位偶数?
解:末尾一定为偶数,共有五种选择。首位不能为零。
分类讨论:
(1).如果末尾不为零,
末尾有四种选择,为C(4,1),首位除去零有八种选择,为C(8,1),中间有余下的八种选择,C(8,1)。
相乘得:256。
(2).如果末尾为零
末尾有一种。首位有九种选择,C(9,1),中间有余下的八种,C(8,1),
相乘得:72。
最后两种情况相加:328。
0xffffffff:吾误唔,呜呜呜……
T1排队:一直w90……不知道为啥……尤其是所有样例无论是手模的还是用题解yy出来的都没毛病。
最后Larry大神帮我对拍(我应该自己对拍的……我忏悔……)发现有些点我的代码不输出,正解是零。
检查代码发现答案数组c[0]记录长度,最后的时候无下限狂减减没了……改掉后就A了……+7,我想死怎么办……
T2perm排列计数:这道题稍微恶心,我就不是人了……
交了六遍才A掉。。。本来打算一遍A的,但是一直TLE82。。。3000多毫秒,对比了一下大神的294毫,我想去死。。。
然后咨询了一下动动神佬,动动神佬说:打表啊~ 我:……
(我会说我一开始连表都没打对吗?顺便提一句,脑残的我在输入p之前就调用了p打表结果表里全是0……
取模了一下,浮点数例外就出来了。不过令我欣慰痛心的是,机房里诸多大佬竟然都死在这个坑里,光来问我的就有五六个。。。)
A掉,700毫秒。坦然了,这个世界没有真理可言……
时限苦短,及时打表啊~
T3:集合计数:拿到这道题一脸懵比(似乎蒟蒻我拿到啥题都能一脸懵比……)所以不是人了……
发现集合计数要想补集。补集……很不幸,又出现了重复的问题。于是又用到了容斥……
容斥挺好打,然而sb的我没想到他会容斥成负……70分调了我两个小时。最后看lsc大神题解这才挣扎出来……
我太菜了……我是sb蒟蒻……