杂记 › 生活随笔 › 选人组队到底多少种?排列与组合别再搞混

选人组队到底多少种?排列与组合别再搞混

去年帮部门排周末值班,题目是"12 个人里选 4 个"。我算出 495,隔壁工位的老周算出 11880。我们把草稿拍在桌上互相验了一下午,最后才发现问题不在计算:回答的压根不是同一个问题。我说的是"哪四个人",他说的是"哪四个人各守哪个岗"。

这之后我又碰到好几回同类争执:抽奖的覆盖率、比赛名单的搭配、四位数字锁的可能性。栽多了,我给自己定了一条很笨但极有用的判据,下面这些数都是逐个算过并核对的。

顺序算不算数,我做"交换测试"

把一个结果原样写下来,任意交换其中两个成员的位置,只问一句:这还算不算新的一种?算,就是顺序算数,用排列;不算就是顺序不算数,用组合。听着像废话,但做成动作之后,绝大多数题目不用再犹豫。

场景 交换两个位置之后 该用哪个 数量
12 人取 4 人,只决定谁上 还是那四个人,名单没变 组合 C(12,4)=495
12 人取 4 人,分别守 4 个不同的岗 班次对不上人,值班表变了 排列 A(12,4)=11880
52 张牌发 5 张,只看牌型 手里同样的五张,牌型不变 组合 C(52,5)=2598960
6 个人互相握一次手 甲握乙与乙握甲是同一次 组合 C(6,2)=15
4 位数字锁,数字不许重复 1234 和 4321 是两把不同的锁 排列 A(10,4)=5040
4 位数字锁,数字可重复 每位独立,各有 10 种 两个都不是 10×10×10×10=10000

最后一行是我每次都要先问的第二件事:可不可重复。同一个人能不能被排两次,同一个数字能不能连按四次。两个公式默认都不重复,一旦允许重复就既不是 A 也不是 C,而是每位独立相乘。

两个公式之间只差一个 r!

排列数 A(n,r) = n! / (n-r)!,组合数 C(n,r) = n! / (r!(n-r)!),差别只在分母多出来的那个 r!,也就是 A(n,r) = C(n,r) × r!。这个关系我很常用,因为它是一次现成的自检:算完两个数除一下,应该正好等于 r 的阶乘,除不平就说明题意认错了。

我核对过的几组:

  • n=12,r=4:C=495,A=11880,比值 24,正好是 4!
  • n=9,r=4:C=126,A=3024,比值 24
  • n=7,r=3:C=35,A=210,比值 6,正好是 3!
  • n=10,r=3:C=120,A=720,比值 6
  • n=6,r=2:C=15,A=30,比值 2

组合数还有两条我拿来手算验错的道路:对称性 C(n,r)=C(n,n-r),例如 C(10,3) 和 C(10,7) 都是 120,所以手算时我总挑 r 与 n-r 里较小的那个,乘法步数少一半;帕斯卡递推 C(n,r)=C(n-1,r-1)+C(n-1,r),例如 C(8,3)=C(7,2)+C(7,3)=21+35=56。前者防我把上下项写反,后者防我漏掉一档。要列全部方案时我不手敲,交给 排列计算器,它把公式与过程一起列出来,方便对着草稿看哪步偏了。

我真正确实算错的三类

第一类就是上面的"可重复"漏问。10000、5040、210 这三个数分别对应同一把四位锁的三种理解,题目只说"四位数字"时我吃过亏。

第二类是"至少"。5 男 7 女里选 3 人,要求"至少有 1 名女生"。我一开始的做法是先定 1 名女生再随便补 2 人:C(7,1)×C(11,2)=7×55=385,当答案交了。正确做法是拿整体减反面:C(12,3)-C(5,3)=220-10=210。多出来的 175 不是笔误:两名女生的组被数了两遍,三名女生的组被数了三遍——按女生人数拆开数是 70+105+35=210,而我那种算法得到 1×70+2×105+3×35=385。这种重复计数不会报错,只有换一种数法才看得见。

第三类是概率的分母。分母必须是完整玩法的组合数而不是其中一步:红球 6/33 加蓝球 1/16,总数是 C(33,6)×16=1107568×16=17721088,只算红球就少了 16 倍。前后两区那种玩法是 C(35,5)×C(12,2)=324632×66=21425712。给个尺度感:2598960 种扑克牌型一天摸一种,要 7120 年才摸完。

数字为什么爆得这么快

两个公式都靠阶乘,而阶乘的增长完全不讲道理。下面是我自己算的对照:

阶乘 值 位数 是否还在 2^53-1 之内
8!403205在
15!130767436800013在
18!640237370572800016在
19!12164510040883200018越线
20!243290200817664000019越线

这里的 2^53-1 是 9007199254740991,浏览器里普通数值类型能精确表示整数的上限。越线的表现不是报错,而是末尾几位悄悄变了,所以 C(20,10)=184756 这种"结果不大、中间量很大"的题最容易骗人:先算 20! 再相除,中间那步早就失真,商却看着像个正常数。C(100,50) 更是 30 位数,100891344545564193334812497256,固定宽度的整数类型装不下。这类题我会明确用支持大数的算法做:组合计算器 的说明写的是基于 BigInt 算大组合数,阶乘计算器 写的是 0 到 1000 的阶乘不溢出。

还有一件我分得很清的事:要"一个数"和要"全部明细"是两个量级。前者算 C 或 A 就够,后者要把每一项写出来,行数按阶乘涨——8 个元素的全排列是 40320 行,9 个是 362880 行,10 个是 3628800 行。这种生成通常是先压垮页面而不是压垮算术,所以工具对元素个数设上限我并不意外;那是实现定的,不是数学限制。

Q:A(n,r) 一定比 C(n,r) 大吗?

大或者相等,不会小,因为 A = C × r!。r=1 时两者都等于 n,r=0 时都等于 1,这是我用来确认公式没写反的两个边界。

Q:为什么 C(10,3) 和 C(10,7) 相等?

选出 3 个和留下 7 个是同一件事的两种说法,一一对应,所以数量必然相同。手算时挑小的那个 r 来算,步骤更少。

Q:从 7 个人里挑 3 个开会,和挑 3 个人分别负责三个不同岗位,差多少?

35 种和 210 种,差 6 倍,也就是 3!。同三个人换一下分工就算新方案,那 6 倍必须乘上。

Q:数字大到算不动了怎么办?

先问是不是真要精确值。比较数量级用约等就够;要精确到个位就不能拿普通数值类型硬算,得换成支持大数的做法,或者先把公式约分再乘。

Q:交上去之前怎么自查?

我固定查三样:A 除以 C 是不是正好等于 r!;有没有把"可重复"的题错用 A 或 C;"至少"是不是改成了整体减反面。三样都过才敢交。

回到开头那张值班表。最后用的是"分岗位"的口径,也就是 11880,因为通知里每人对应一个班次,交换位置就是一份新表。但如果讨论的是"要不要干脆随机凑人",495 才是该说出口的量——按它排轮值,一年都轮不重。谁对谁错不重要,先说清交换之后算不算新的一种。

📎 相关文章

分数加减法通分总出错?把过程一步步看明白 2026-10-15 天干地支纪年怎么算?生肖与干支日的对应 2026-10-15 距离过年还有多少天?节日倒数的日期怎么算 2026-10-15 过年叫不出亲戚称呼?"爸爸的姐姐的儿子"到底叫啥 2026-10-15 一天到底消耗多少卡路里?算算你的基础代谢BMR 2026-10-15