• 组合数学学习笔记


    我会说这是个坑吗

    蒟蒻开始学组合数学了……

    尽管我在认真,刷题速度和学习进度还是要被大佬们甩好几条街……

    忙着刷题后期肯定没办法写总结,

    就只好一边学习一边填坑啦啦啦。

    ^上面的都是废话^


     

    一、什么是组合数学(完全没用,建议跳

    对于很多计数类问题

    由于方案数过于巨大,

    我们无法用搜索的方式来解决问题

    因此我们需要对计数类问题进行一些优化

    这些优化就是组合数学研究的内容

    :(没错就是研究计数类问题)


    二、基本原理

    加法原理:如果完成一件事有两类方法,第一类方法有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蒟蒻……

  • 相关阅读:
    贮油点问题(C++)
    二维数组操作
    二的幂次方(递归)
    [haoi2009]巧克力
    距离最远的牛
    ssh注解basedao简单的实现
    @service中构造方法报错
    spring注解 构造函数问题
    json与gson
    AsyncTask异步类的简单操作
  • 原文地址:https://www.cnblogs.com/xingmi-weiyouni/p/11083980.html
Copyright © 2020-2023  润新知