CSP-J 初赛(以满分为目标):第三十八课《数学与逻辑①——排列还是组合?先搞清楚“选”与“排”》


第三十八课:数学与逻辑①------排列还是组合?先搞清楚"选"与"排"

前面我们用了很多课学习图、树、DFS、BFS、最短路、最小生成树、拓扑排序。现在正式进入"数学和逻辑"篇章。

这一章看起来不像编程,其实和信息学竞赛关系非常密切:很多初赛题目不是让你写程序,而是考你能不能快速数清楚"到底有多少种可能"。

"组合数学基础"首先就是从排列与组合开始,特别强调:

排列与元素的顺序有关,而组合与元素的顺序无关。

今天这一课,我们只解决一个最核心的问题:

什么时候用排列?什么时候用组合?


一、今天的冒险任务:三位小朋友选队长

有三个小朋友:

  • 小明

  • 小红

  • 小刚

现在要从他们中选出两个人。

问:

一共有多少种选法?

我们可以一个一个写:

  1. 小明、小红

  2. 小明、小刚

  3. 小红、小刚

所以答案:

3

但是现在换一个问题:

从三个人中选出队长和副队长各一名,有多少种方法?

这次就不一样了。

例如:

  • 小明队长,小红副队长

  • 小红队长,小明副队长

虽然都是"小明+小红",但是职位不同,所以是两种方法

于是:

6

这就出现了今天最重要的一组概念。


二、组合:只关心"选了谁"

比如:

3个人中选2个人去参加比赛。

小明、小红:

复制代码
小明 + 小红

复制代码
小红 + 小明

是不是两种?

不是。

因为比赛只关心:

谁参加了?

不关心谁先写名字。

所以:

组合:只选,不排列


一个非常重要的判断方法

看到题目先问自己:

"换一下顺序,算不算一种新的结果?"

如果:

不算

就是组合

例如:

5个人中选2个人参加比赛。

A、B 和 B、A:

复制代码
AB
BA

实际上是同一组选手。

所以用:


三、排列:不仅要"选",还要"排位置"

再看:

5个人中选出冠军、亚军、季军。

这里选出来的三个人还要分:

复制代码
冠军
亚军
季军

例如:

复制代码
小明、小红、小刚

复制代码
小红、小明、小刚

虽然三个人完全一样,但是:

复制代码
第一名变了
第二名变了

所以是不同结果。

这就是:

排列:选出来以后,还要安排顺序


四、排列为什么比组合多?

还是用三个小朋友:

复制代码
A   B   C

选择两个。

第一步:先选两个人

有:

复制代码
AB
AC
BC

一共:

种。

但是如果要安排第一名、第二名:

对于 AB:

复制代码
AB
BA

有2种。

对于 AC:

复制代码
AC
CA

有2种。

对于 BC:

复制代码
BC
CB

有2种。

所以:

3×2=6

这就是一个非常重要的思想:

排列=先选,再排

特别提醒:

分清排列"先取再排"和组合"只取不排"。


五、用"座位"理解排列

这是给小学生特别好用的一种理解方法。

假设有3个人:

复制代码
A B C

现在有两个座位:

复制代码
第1名    第2名

第1个位置有3种选择:

复制代码
A / B / C

假设第一位选了 A。

那么第二位只能从:

复制代码
B / C

里面选。

所以:

3×2=6

种。

因此:


六、排列的公式从哪里来?

假设:

n个人中选出m个人,并安排顺序。

第一个位置:

n

种。

第二个位置:

n−1

种。

第三个位置:

n−2

种。

......

第m个位置:

n−m+1

种。

所以:

例如:

5个人中选3个人排前三名。

就是:


七、组合到底是怎么来的?

我们已经知道:

表示:

选出m个人,并且排列顺序。

但是组合只需要:

选出m个人。

问题来了:

同一组m个人到底被排列了多少次?

假设已经选出了:

复制代码
A B C

那么这三个人可以排列成:

复制代码
ABC
ACB
BAC
BCA
CAB
CBA

一共有:

3!=6

种。

所以:

因此:

这就是组合公式。


八、组合公式

于是得到:

其中:

叫做n的阶乘

例如:

5!=5×4×3×2×1=120

所以:

也可以直接计算:


九、小学生最容易犯的错误:看到"选"就用组合

这是初赛里非常危险的地方。

例如:

题目1

8个人中选3个人参加比赛。

关键词:

复制代码
选3个人

没有职位,没有顺序。

所以:


题目2

8个人中选出冠军、亚军、季军。

虽然也写着:

复制代码
选3个人

但实际上还要安排:

复制代码
冠军
亚军
季军

所以:


十、"先选后排"是一个超级重要的思想

来看一个典型问题:

6个人中选出3个人,分别担任队长、副队长、秘书。

不要直接背公式。

我们可以:

第一步:选出3个人

第二步:给3个人安排职位

3!

所以:

也就是:

20×6=120

答案:

120

这就是:

先选后排


十一、一个特别容易考的陷阱:指定顺序

有这样一句话,非常值得孩子记下来:

按指定的一种顺序排列的问题,实质是组合问题。

什么意思?

例如:

5个人排成一列,但是要求按照年龄从小到大排列。

表面上看:

复制代码
排成一列

好像应该用排列。

但是实际上:

一旦选定了这5个人,顺序已经被"年龄从小到大"唯一确定

例如选:

复制代码
A B C

如果年龄已经确定:

复制代码
A < B < C

那么只能:

复制代码
A B C

不能再:

复制代码
B A C

所以实际上只是:

选哪些人

而不是:

怎么排列

因此属于组合思想。


十二、一个万能判断器

以后做排列组合题,不要先看公式。

先问两个问题。

问题1:是在"选人"吗?

如果是,继续问第二个问题。

问题2:换一下顺序,结果会不会改变?

不改变

组合

会改变

排列

可以记成:

复制代码
                选出来
                   ↓
          换顺序会不会改变结果?
             ↙           ↘
           不会           会
            ↓             ↓
          组合           排列

十三、生活中的例子

我们自己判断。

例1:班级里选3个人去春游

只关心谁去。

所以:

组合


例2:班级里选班长、副班长、学习委员

职位不同。

所以:

排列


例3:从10本书中选3本带回家

只关心带哪三本。

组合


例4:从10本书中选3本,分别放在书架第1、2、3层

位置不同。

排列


例5:从10名同学中选5名组成一个小组

组合


例6:从10名同学中选5名,排成一列

排列


十四、和C++有什么关系?

有的同学可能会问:

"老师,这不是数学课吗?为什么放在CSP-J初赛?"

因为计算机特别喜欢问:

"一共有多少种可能?"

例如:

复制代码
for(int i = 1; i <= 3; i++)
{
    for(int j = 1; j <= 3; j++)
    {
        if(i != j)
            cout << i << " " << j << endl;
    }
}

这里实际上是在做:

复制代码
从 1、2、3 中选择两个不同的数
并且考虑顺序

得到:

复制代码
1 2
1 3
2 1
2 3
3 1
3 2

一共:

所以:

排列组合,是很多枚举程序背后的数学。


十五、如果不考虑顺序,程序就会重复

例如我们想找:

1、2、3中任意选两个。

如果直接:

复制代码
for(int i = 1; i <= 3; i++)
{
    for(int j = 1; j <= 3; j++)
    {
        if(i != j)
            cout << i << " " << j << endl;
    }
}

会出现:

复制代码
1 2
2 1

可是对于"选两个人"来说:

复制代码
1 2

和:

复制代码
2 1

其实是同一种。

怎么办?

让:

复制代码
j > i

例如:

复制代码
for(int i = 1; i <= 3; i++)
{
    for(int j = i + 1; j <= 3; j++)
    {
        cout << i << " " << j << endl;
    }
}

输出:

复制代码
1 2
1 3
2 3

正好:

这就是:

组合 = 枚举时主动消除"顺序重复"。

这个思想以后学习中会经常出现。


十六、排列和组合的关系

今天一定要把这张图记住:

复制代码
排列
  │
  │  把顺序考虑进去
  ↓
先选出 m 个
  │
  ↓
再把这 m 个进行排列
  │
  ↓
组合 × m!

所以:

反过来:

这是两者最重要的关系。


十七、排列与组合中的典型思路

后面我们还会提到,一些非常重要的方法:

  • 特优法:优先处理特殊元素或特殊位置

  • 捆绑法:要求某些元素相邻时,把它们先看成一个整体

  • 插空法:要求某些元素不相邻时,先排其他元素,再插进去

  • "至多""至少":通常考虑排除法或分类

  • 多面手问题:通常分类解决

这些内容今天先不展开,后面的课会逐个拆开。


十八、课堂小测:先不要算,先判断

题1

5个人中选2个人参加比赛。

是排列还是组合?

答案:组合。


题2

5个人中选出冠军和亚军。

答案:排列。


题3

从8本不同的书中选3本。

答案:组合。


题4

从8本不同的书中选3本,分别放在第1、2、3层。

答案:排列。


题5

从10个人中选3个人组成小组,然后按照年龄从小到大站成一排。

答案:组合。

为什么?

因为:

顺序已经被年龄规则唯一确定了。


十九、计算题

题6

6个人中选3个人参加比赛,有多少种方法?

答案:

20


题7

6个人中选出冠军、亚军、季军,有多少种方法?

答案:

120


题8

7个人中选3个人,然后分别担任队长、副队长、秘书。

先选:

再排:

3!=6

所以:

35×6=210

答案:

210


二十、今天同学们必须记住的"四句话"

第一句

组合:只选,不管顺序

第二句

排列:选出来,还要考虑顺序

第三句

排列=先选后排

第四句

遇到题目先问:

"换一下顺序,算不算一种新的结果?"

复制代码
不算 → 组合
算   → 排列

二十一、今天真正应该建立的数学思维

这一课表面上是在学习两个公式:

但对于我们小学生,我更希望你们真正学会的是:

不要一看到公式就套公式。

而应该先问:

复制代码
题目到底在数什么?
        ↓
是"选谁"?
还是"怎么安排"?
        ↓
换顺序会不会产生新结果?
        ↓
再决定用组合还是排列

这其实和我们前面学习算法时的思想完全一致:

先理解问题,再选择工具。


📌 课后作业

第一步必须写"排列/组合"以及为什么。

  1. 10人中选4人参加比赛。

  2. 10人中选4人分别担任4个不同职位。

  3. 6本书中选3本带回家。

  4. 6本书中选3本分别放到3个不同书架。

  5. 8名同学中选5名组成小组。

  6. 8名同学中选5名,按身高从低到高排队。

  7. 7个人中选3个人参加比赛,再选出其中的队长。

  8. 从1~9中选出3个不同数字组成一个三位数。

第8题尤其值得讲一讲。因为它会让同学们发现:

"选3个数字"是组合,

但"组成三位数"以后,位置就产生了意义,因此最终属于排列思想。

这正好为下一课的阶乘、排列数 、组合数做准备。


相关推荐
qeen871 小时前
【C++】智能指针介绍
开发语言·c++·笔记·指针
Lionel_Coder1 小时前
matmul 总体设计
c++
Dream Cosmos1 小时前
C++ 中 static 关键字的作用与使用规则
linux·c++
蒸蒸yyyyzwd4 小时前
cpp 选手秋招学习笔记 day33
c++·笔记·求职招聘
hansang_IR10 小时前
【题解】P4460 [CQOI2018] 解锁屏幕
c++·算法
ChampaignWolf11 小时前
在 SAP S/4HANA 内部基于 ICF Handler 从零实现 ABAP MCP Server:架构、代码与踩坑实录
c++·架构·sap·abap·mcp
尘客-追梦12 小时前
Day 01:插件化之前,先看清 ABI 这堵墙
开发语言·c++·qt
有点。13 小时前
*C++哈夫曼树与哈夫曼编码
java·c++·servlet
啦啦啦啦啦zzzz13 小时前
利用RAII机制进行日志的采集
linux·服务器·c++·网络编程·c++20