组合数学学习笔记

其实只是没什么写题的心情,也不想摆,于是就来做一些组合计数的题,然后记录在这里...

基础知识

1.加法原理与乘法原理

加法原理:

如果一件做一件事的方法可以分为$n$个互不相同的类,并且其中的第$i$类有$m_i$种方法

那么完成这件事一共有$sumlimits_{i = 1}^n m_i$种方法

 

乘法原理:

如果一件事要分$n$步,并且其中的第$i$步有$m_i$种方法

那么完成这件事一共有$prodlimits_{i = 1}^n m_i$种方法

 

2.无重复的排列组合

排列:

从$n$个元素中,有序地取出$m$个元素称作$n$个数中取$m$个数的排列

记为$P_n^m$,或者$A_n^m$

由乘法原理,可以得到$P_n^m = frac{n!}{(n - m)!}$

 

组合:

从$n$个元素中,无序地取出$m$个元素称作$n$个数中取$m$个数的组合

记做$C_n^m$,并且有$C_n^m = P_n^m * frac{1}{m!} = frac{n!}{m!(n- m)!}$

 

3.斯特林数

第一类斯特林数:

把$n$个不同的小球放进$m$个相同的圆排列,记为$s(n, m)$

$s(n + 1, m) = s(n, m - 1) + n * s(n, m)$

 

第二类斯特林数:

把$n$个不同的小球放进$m$个相同的盒子,记为$S(n, m)$

$S(n + 1, m) = S(n, m - 1) + m * S(n, m)$

 

4.二项式定理

$$(a + b)^n = sumlimits_{i = 0}^n a^i b^{n - i} inom{n}{i}$$

常用的二项式定理的其他形式:

$$(1 + 1)^n = 2^n = sumlimits_{i = 0}^n * inom{n}{i}$$

$$(1 - 1)^n = 0 = sumlimits_{i = 0}^n (-1)^i * inom{n}{i}$$

$$(2 - 1)^n = 1 = sumlimits_{i = 0}^n 2^i * (-1)^{n - i} * inom{n}{i}$$

$$(2 + 1)^n = 3^n = sumlimits_{i = 0}^n 2^i * inom{n}{i}$$

$$(1 + x)^n = sumlimits_{i = 0}^n x^i * inom{n}{i}$$

 

5.卡特兰数

对于给定的长为$n$的入栈序列,对应的可能的出栈数列的方案数

记做$C_n$

$C_n = C(2n, n) - C(2n, n - 1)$

$C_n = frac{C(2n, n)}{n + 1}$

$C_n = C_{n - 1} * frac{4n - 2}{n + 1}$

$C_n = sumlimits_{i = 0}^{n - 1} C_i * C_{n - i - 1}$

 

6.容斥原理

公式有点难打,就不打了,应该都知道吧...

还有一个排斥原理,跟容斥原理很相近

(容斥原理其实是一种套路)

 

 

基础知识点差不多就这么多吧

只要你够强,什么都可以推出来的...

通过大量的练习来锻炼计数的能力吧

 

练习

部分题目是口胡的,如果发现不对请指出

大部分例题来源于《奥林匹克数学中的组合问题》,但是笔者或多或少有加强

T1.忐忑子集

如果${1, 2, ..., 9}$的某个非空子集中所有元素之和是3的倍数,则称该子集为忐忑子集,试问有多少忐忑子集

爆搜一下就出来了

 

 

让我们先来看看数学组的方法:

如果${1, 2, ..., 9}$的某个非空子集是忐忑子集,那么它的补集也是忐忑子集.

因此,我们只需考虑元素$leqslant 4$的忐忑子集的个数.

只有1个元素的忐忑子集有$3$个

两数之和被3整除的充要条件是两个数被3除的余数只能是$(0, 0), (1, 2)$

而被$3$除余数为$0, 1, 2$的各有$3$个,因此含$2$个元素的忐忑子集的个数为$inom{3}{2} + inom{3}{1} * inom{3}{1} = 12$

含有3个元素只可能是$(0, 0,0 ), (1, 1, 1), (2, 2, 2), (0, 1, 2)$,因此有${inom{3}{1}}^3 + 3 * inom{3}{3}$种方案

含有4元素同理只可能是$(0, 0, 1, 2), (1, 1, 1, 0), (0, 2,2,2), (1, 1, 2, 2)$,对应有$42$种方案

全集也是一个忐忑集合

因此最终有$2(3 + 12 + 30 + 42) + 1 = 175$种

 

非常漂亮的思路

下面我们再看看信息组的做法...

设$f[i][0 / 1/ 2]$表示在集合${1, 2..., i}$中和模3的余数为$0, 1, 2$的子集有多少个

那么每次新增$i + 1$时,考虑选或不选转移即可

复杂度$O(n)$

#include <cstdio>
using namespace std;

int f[20][3];

int main() {
    f[1][0] = 1; f[1][1] = 1;
    for(int i = 1; i <= 10; i ++)
    for(int j = 0; j <= 2; j ++) {    
        f[i + 1][j] += f[i][j];
        f[i + 1][(i + 1 + j) % 3] += f[i][j];
    }
    printf("%d
", f[9][0] - 1);
    return 0;
}

简单多了,不是吗....

 

那么,我们能做到$O(1)$吗?答案是可以的(其实是$O(log n)$)

下面的$i / 3$默认下取整

当$i;mod;3 = 0$时,$f[i][0 / 1 / 2]$分别为$frac{2^i + 2*2^{i / 3}}{3}, frac{2^i - 2^{i / 3}}{3}, frac{2^i - 2^{i / 3}}{3}$

当$i ;mod;3 = 1$时,$f[i][0 / 1/ 2]$分别为$frac{2^i + 2^{i / 3}}{3}, frac{2^i + 2^{i / 3}}{3}, frac{2^i - 2*2^{i / 3}}{3}$

当$i;mod;3 = 2$时,$f[i][0 / 1 / 2]$分别为$frac{2^i + 2*2^{i / 3}}{3}, frac{2^i - 2^{i / 3}}{3}, frac{2^i - 2^{i / 3}}{3}$

快乐矩乘不就完事了

 

T2.运动会

安排$n$名同学参加$m$个运动项目,要求甲乙两同学不参加同一项目,且每个项目都有人参加,每个人只参加一个项目,求满足要求的不同方案数

 

补集转化

首先,$n$个不同的人放进$m$个相同的盒子的方案数为$S(n, m)$,即第二类斯特林数(百度百科?)

$n$个不同的人放进$m$个不同的盒子的方案数记做$f(n, m) = S(n, m) * m!$

暂时不考虑甲乙同学,那么有$f(n, m)$种可能

再考虑甲乙同学,把两个人看做一个整体,那么方案数有$f(n - 1, m)$种

最终答案即为$f(n, m) - f(n - 1, m)$

复杂度$O(n^2)$

T3.选集合

设集合${1, 2, ..., n}$,选择此集合的两个子集$A, B$,满足$max(A) < min(B)$,问方案数

其实不怎么难的一道题?

首先,问题在于枚举什么然后计数,一直想着去枚举$A$然后去判断$B$,发现不太好做....

一种神奇的思路是枚举$|A cup B|$,确定了并集大小后,相当于只要在并集内部放一块分隔板就行了

因此,总方案为$sumlimits_{i = 2}^n (i - 1)C(n, i)$

然而后面的组合恒等式变形感觉更是神奇...$ = sumlimits_{i = 1}^n iC(n, i) - sumlimits_{i = 1}^n C(n, i)$

这里有一个组合恒等式,$kC(n, k) = nC(n - 1, k - 1)$,考虑选出单独的一个元素即可

$= nsumlimits_{i = 1}^n C(n - 1, i - 1) - sumlimits_{i =  1}^n C(n, i)$

$= n sumlimits_{i = 0}^{n - 1} C(n- 1, i) - sumlimits_{i = 0}^n C(n, i) + 1$

$ = n * 2^{n - 1} - 2^n + 1$

(对于$i C(n, i)$的求和感觉值得记忆)

另一种思路是枚举$max(A), min(B)$然后计数,和式的变换比起上面的方法难度小了许多

也许我们可以想想划分成$3$个集合甚至$m$个集合的情况.....

T4.正方体染色

你现在拥有$n$种颜色,你可以从中选出若干种颜色,将一个正方体的六个面染色,每面恰染一色,具有公共棱的两个面不共色,问不同的染色方案数

(这里,我们认为存在翻转和旋转两种置换)

首先,我们是不会用超过$6$种颜色的,也不会少于$3$种颜色,因此,实际上只需要对$3, 4, 5, 6$进行计数就好了

只用3种颜色时,先考虑染3面,可以发现之后的所有面的颜色都被固定,因此一共有$C(n, 3) * 1$种

令上前右下后左面分别为$1, 2, 3, 4, 5, 6$面

只用4种颜色时,先染好$1, 2, 3$面,假定它们的颜色为$a, b, c$,那么第$4$面有$a, d$两种选择

选择$a$时,$5, 6$有两种不同的方案,选择$d$时,$5, 6$只有一种方案

但是,我们发现每种方案都被我们统计了两次(比如开局$a, b, c$和$a, c, b$就有一个重复的方案)

因此,最终方案数为$C(n, 4) * C(4, 3) * 3 * frac{1}{2} = C(n, 4) * 6$种方案

使用5种颜色时,随便染好5不相同的面后,剩下的一面一定会和对面相同

因此,相当于我们挑一组对面出来,染一种颜色后,剩下4面再4染色

但是要去重,可以发现每组对面对应的方案都是重叠的,只要对一组对面计数即可,剩下4面也要注意不重叠

剩下4面不重叠的方案数手动枚举下发现是3(4! / 4 / 2,/ 4表示旋转,/ 2表示翻转)

那么有$C(n, 5) * 5 * 3 = C(n, 5) * 15$种方案

使用6种颜色时,先染好$1, 2, 3$面,有$C(6, 3)$种方法

剩下3面可以自行安排颜色的顺序,因此有$6$种方法

考虑重复,对于一个正方体,前,后,左,右转都会被记1次

因此总共有$C(n, 6) * 6 * C(6, 3) / 4 = C(n, 6) * 30$种

从这里我们可以看出组合计数的分类讨论堪称各种脑洞展开.....

其实我们可以选择用电脑来统计,反正有电脑就是能任性啊......

T5.解方程(一)

求解不定方程$x_1 + x_2... + x_k = n$的方程组的非负整数解的组数

我们可以认为我们有$n + k - 1$个空,$k - 1$个板子随意地插入到其中

特别的,$0$号板子在最前面,$k$号板子在最后面(这两块板子被固定了位置)

那么,我们可以认为$p_i - p_{i - 1} - 1$代表了原方程的$x_i$,其中$p_i$表示第$i$块板子的位置

不难发现,这种办法与原问题存在一一映射的关系

T6.解方程(二)

求解不定方程$x_1 + x_2... + x_k = n$的方程组的非负整数解的组数

其中$x_i geqslant a_i$

嗯.......跟上面其实没有很大差别

令$x_i' = x_i - a_i$,那么$x_i' geqslant 0$

代入到原方程,那么$x_1' + x_2' + ... + x_k' + a_1 + a_2 + ... + a_k = n$

得到一个新方程$x_1' + x_2' + ... x_k' = n - a_1 - a_2 ... - a_k$

跟上面回到了一个问题

 

T7.解方程(三)

求解不定方程$x_1 + x_2... + x_k = n$的方程组的非负整数解的组数

其中$x_i leqslant a_i$

嗯.......其实也没什么太大区别

上面的能$O(n)$,这个要$O(2^n)$而已......

考虑使用容斥原理

那么,转化条件后,只要求出一些$x_i geqslant 0$,一些$x_i geqslant a_i$,然后用全集减去就好啦

接连3道都是套路题呢......

原文地址:https://www.cnblogs.com/reverymoon/p/9499304.html