📸

组合:顺序没关系的计数

合影只看「谁在框里」,站哪都一样——顺序没关系的计数 = 排列数 ÷ k!。

💡 打个比方

甲乙丙三人合影:拍出来是「甲乙丙」还是「丙甲乙」?照片里还是同样三个人——换位置还是同一张照片。这种「只看谁在框里、不看顺序」的计数叫组合,数记作 C(n,k)。

怎么算?先按排列数:4 人选 3 人去值日(不分工),先「排」1、2、3 号位:A(4,3) = 4×3×2 = 24;可同一组 3 个人可以排出 3! = 6 种「站位」,它们其实是同一组。所以组数要把排列数除以 k!:C(4,3) = 24 ÷ 6 = 4 组——枚举验证:甲乙丙、甲乙丁、甲丙丁、乙丙丁,正好 4 组。

公式:C(n,k) = A(n,k) ÷ k!。「除以 k!」的直觉:同一组 k 个人有 k! 种站位,排列把它们全数了一遍,除以 k! 就只留「组」了。

术语:组合(Combination:从 n 个里选 k 个,不分顺序);C(n,k)(组合数:C(n,k) = A(n,k) ÷ k!,例如 C(4,2) = 4×3 ÷ 2 = 6);「除以 k!」(同一组 k 个人有 k! 种排队方式,排列把每种站位都数了,所以要除回去);握手问题(n 人两两握手,每对 1 次,总次数 = C(n,2))。

🖼️ 大图看明白

左边:合影只看谁在框里;握手每人一对 甲 乙 丙 丙 甲 乙 ≡ 框里:甲乙丙 框里:丙甲乙(同一组) 5 人两两握手 1 2 3 4 5 C(5,2) = 5×4 ÷ 2 = 10 次 4 人选 2 的全部 6 对 甲乙 甲丙 甲丁 乙丙 乙丁 丙丁 C(4,2) = 12 ÷ 2 = 6 对 右边:为什么「除以 k!」? 第一步:先按排列数 4 人选 2 个排队:A(4,2) = 4 × 3 = 12 「甲乙」和「乙甲」被当成两种数了(顺序) 第二步:同一组人有 k! 种站位 同一对人 {甲,乙} 有 2! = 2 种排队:甲乙、乙甲 每对都被数了 2 遍 → 排列数「数重了 k! 倍」 第三步:除以 k!,只留「组」 C(4,2) = A(4,2) ÷ 2! = 12 ÷ 2 = 6 一般:C(n,k) = A(n,k) ÷ k! 合影只看谁在框里 → 组合;黑板上有分工 → 排列

🧩 子任务 1:什么是组合——「先排后除」

🎯 小目标:理解「从 n 个里选 k 个,不分顺序」,会手推 C(4,3) = 4、C(4,2) = 6,记住公式 C(n,k) = A(n,k) ÷ k!。

4 人(甲乙丙丁)选 3 人值日,不分工——只要「谁值日」一样,就是同一组。顺序没关系,用组合数 C(4,3)。

怎么算?先排后除:先按排列算 A(4,3) = 4 × 3 × 2 = 24。但注意:同一组 3 个人(比如甲乙丙)可以排出 3! = 3 × 2 × 1 = 6 种「站位」,排列把 6 种站位全数了一遍。要数「组」,就得把重复的站位除掉:

// 手推 C(4,3):先排后除
C(4,3) = A(4,3) ÷ 3!
      = (4 × 3 × 2) ÷ (3 × 2 × 1)
      = 24 ÷ 6
      = 4 // 一共 4 组

// 枚举 4 组,验证公式:
1: 甲乙丙   2: 甲乙丁
3: 甲丙丁   4: 乙丙丁
// 正好 4 组,和公式一致 ✓

// 一般公式:C(n,k) = A(n,k) ÷ k!
// 「除以 k!」的直觉:同一组 k 个人有 k! 种站位,
// 排列把每种站位都数了,除以 k! 就只剩「组」了。
C(4,2) = A(4,2) ÷ 2! = 12 ÷ 2 = 6 // 子任务 2 会枚举验证
✅ 小检查:① C(4,3) 和 A(4,3) 分别数什么?哪个数「谁在框里」,哪个数「谁站哪个位」?② 为什么 C(n,1) = n?③ 算一算 C(5,3) = A(5,3) ÷ 3! = ?
看看答案 ① C(4,3) 数组(顺序没关系),A(4,3) 数排法(顺序有关系)。② 从 n 个里选 1 个,就是选 1 个人;1 个人只有 1! = 1 种站位,C(n,1) = A(n,1) ÷ 1! = n ÷ 1 = n。③ C(5,3) = 60 ÷ 6 = 10。
易错:C(4,2) = 4 × 3 = 12——12 是排列数 A(4,2)!组合别忘除以 k! = 2:12 ÷ 2 = 6。

🧩 子任务 2:手推 C(4,2) = 6——每对被数了两遍

🎯 小目标:枚举 4 人选 2 人的全部 6 对,体会「除以 k!」除掉的正是重复计数。

4 人(甲乙丙丁)选 2 人一组。按固定顺序枚举(每对的第 1 个人必须排在第 2 个人前面):

// 枚举全部 C(4,2) 对——固定顺序,每对只出现一次:
甲在一对里:甲乙, 甲丙, 甲丁     // 3 对
乙在一对里(甲乙已数过):乙丙, 乙丁 // 2 对
丙在一对里:丙丁               // 1 对
→ 3 + 2 + 1 = 6 对 = C(4,2) ✓

// 对照排列 A(4,2) = 12:12 种排法长这样——
甲乙 乙甲 甲丙 丙甲 甲丁 丁甲 乙丙 丙乙 乙丁 丁乙 丙丁 丁丙
// 每一「对」恰好出现两次(两种顺序都有),
// 12 ÷ 2 = 6。除以 k! 除掉的,正是这份重复。
✅ 小检查:① 枚举时为什么「乙在一对里」只数 2 对,而不是 3 对?② 4 个人每两人握一次手,一共握几次?(提示:一次握手 = 一对)③ C(6,2) = 15:先数出含甲的对有几对,再说明剩下的 10 对是从哪里来的。
看看答案 ① 含乙的 3 对是「乙甲、乙丙、乙丁」,但「乙甲」和「甲乙」是同一对,甲那轮已经数过——每对只数一次,所以乙这轮只剩 2 对新的。② 一次握手就是一对人,C(4,2) = 6 次。③ 含甲的对:甲乙、甲丙、甲丁、甲戊、甲己,共 5 对;剩下的 10 对是不含甲的 5 个人(乙丙丁戊己)两两配对,C(5,2) = 10。5 + 10 = 15 ✓。
易错:枚举时把「甲乙」和「乙甲」都写进去——那是数排列了。枚举组合要用固定顺序(第 1 个人永远排前面),每对才会恰好出现一次。

🧩 子任务 3:排列还是组合?——「有没有分工」

🎯 小目标:读题判断用排列还是组合。判断口诀:「有没有分工 / 顺序」——换两个人位置,情况算不算变。

同样是「4 人(甲乙丙丁)选 2 人去黑板」,两句话差别很大:

// 情境 A:2 人去黑板,不分工作(一起上去就行)
// 「甲乙」和「乙甲」是同样两个人 → 顺序没关系 → 组合
C(4,2) = 12 ÷ 2 = 6 种

// 情境 B:2 人去黑板,一人写、一人擦
// 「甲写乙擦」≠「乙写甲擦」→ 顺序有关系 → 排列
A(4,2) = 4 × 3 = 12 种

// 判断口诀:读完题,问自己一句——
// 「把选出来的两个人换一下位置,算同一种还是不同种?」
// 同一种 → 组合 C(n,k);不同种 → 排列 A(n,k)
// 有分工(班长/副班长、写/擦、先手/后手)→ 一般都有顺序
✅ 小检查:① 5 人选 3 人去春游(不分角色):用排列还是组合?算出结果。② 5 人选 3 人当班长、副班长、宣传委员:用哪个?算出结果。③ 什么时候 C(n,k) 和 A(n,k) 的值相等?(想想哪个 k 特殊)
看看答案 ① 不分工作 → 组合:C(5,3) = A(5,3) ÷ 3! = 60 ÷ 6 = 10。② 三个职位不同 → 排列:A(5,3) = 5 × 4 × 3 = 60。③ k = 1 时:C(n,1) = A(n,1) ÷ 1! = n ÷ 1 = n = A(n,1)——只选 1 个人时,根本没有「顺序」可言,两者相等。
易错:看到「选 k 个」就条件反射写 C(n,k)——先读题看有没有分工:有分工(谁当什么、谁先谁后)就有顺序,要用排列 A(n,k)。

🧩 子任务 4:握手问题——每两人一次

🎯 小目标:理解「n 人两两握手,总次数 = C(n,2)」,会用「n×(n−1)÷2」和「C(n,2)」两种算法,并且会解释为什么要除以 2。

5 人(甲乙丙丁戊)两两握手,每对人只握一次。一共握多少次?

// 算法一:按人数,再消重复
每人和其余 4 人各握一次:5 × 4 = 20
// 但「甲和乙握」与「乙和甲握」是同一次握手,
// 每次握手被两个人各数了一遍 → 20 ÷ 2 = 10 次

// 算法二:一次握手 = 选出「一对人」→ 就是 C(5,2)
C(5,2) = A(5,2) ÷ 2! = (5 × 4) ÷ 2 = 10 次  // 两种算法一致 ✓

// 一般:n 人两两握手总次数 = C(n,2) = n × (n − 1) ÷ 2
n = 4: 4 × 3 ÷ 2 = 6    // 和子任务 2 的 6 对对上号
n = 6: 6 × 5 ÷ 2 = 15
n = 10: 10 × 9 ÷ 2 = 45
✅ 小检查:① 10 人的聚会,每两人握一次手,一共握多少次?② 6 个人打乒乓球,每两人打一局(循环赛),一共几局?③ 为什么按人数算要除以 2?3 个人每两人打一场 100 米(每对打一场),一共几场?
看看答案 ① C(10,2) = 10 × 9 ÷ 2 = 45 次。② 一局 = 一对人 → C(6,2) = 6 × 5 ÷ 2 = 15 局。③ 握手是对称的:A 和 B 握 = B 和 A 握,按人数数时每场被双方各数一遍,所以除以 2。3 人每对一场:3 × 2 ÷ 2 = C(3,2) = 3 场(甲乙、甲丙、乙丙)。
易错:5 人 × 4 次 = 20,直接答 20——每次握手被数了两遍(甲那遍、乙那遍)。凡是「每两人一次」的问题(握手、比赛、配对),人数算出来都要除以 2。

💻 完整代码:组合计算器(算 C(n,k) = A(n,k) ÷ k!,小例子枚举,算握手)

// 输入:n, k(1 ≤ k ≤ n ≤ 13,结果用 long long 防溢出)
// 输出:① A(n,k) 和 C(n,k) = A(n,k) ÷ k!(展示过程)
//       ② n 人两两握手总次数 = C(n,2) = n × (n − 1) ÷ 2
//       ③ 若 n == 4 且 k == 2,枚举全部 C(4,2) 对(A B C D 代表 甲乙丙丁)
// 示例:输入 4 2 → A(4,2) = 12, C(4,2) = 6,列出 6 对,握手 6 次
#include <iostream>
using namespace std;

long long A(int n, int k) {       // 排列:k 个递减因子连乘
    long long res = 1;
    for (int i = 0; i < k; i++)
        res *= (n - i);
    return res;
}

long long fact(int x) {           // 阶乘:x! = 1 × 2 × … × x
    long long res = 1;
    for (int i = 2; i <= x; i++)
        res *= i;
    return res;
}

long long C(int n, int k) {       // 组合 = 排列 ÷ k!(整数除法)
    return A(n, k) / fact(k);
}

int main() {
    int n, k;
    cin >> n >> k;
    cout << "A(" << n << "," << k << ") = " << A(n, k) << endl;
    cout << "C(" << n << "," << k << ") = " << A(n, k)
         << " ÷ " << fact(k) << " = " << C(n, k) << endl;
    cout << n << " 人两两握手 = C(" << n << ",2) = "
         << C(n, 2) << " 次" << endl;

    if (n == 4 && k == 2) {       // 小例子:枚举全部对
        char p[] = { 'A', 'B', 'C', 'D' };
        int cnt = 0;
        for (int i = 0; i < 4; i++)
            for (int j = i + 1; j < 4; j++) { // j 从 i+1 起:固定顺序,不重不漏
                cnt++;
                cout << cnt << ": " << p[i] << p[j] << endl;
            }
    }
    return 0;
}
// 动手验证:输入 5 2 → A(5,2) = 20, C(5,2) = 10, 握手 10 次
// 输入 6 3 → A(6,3) = 120, C(6,3) = 20, 握手 15 次

✋ 你来试试

第 1 题:算 C(7,2) 和 C(7,3)。 C(7,2) = 7 × 6 ÷ 2 = 21;C(7,3) = A(7,3) ÷ 3! = (7 × 6 × 5) ÷ 6 = 35。
第 2 题:8 人选 3 人组成学习小组(不分角色),有多少种选法? 不分角色 → 组合:C(8,3) = (8 × 7 × 6) ÷ 6 = 56 种。注意 8 × 7 × 6 里的 6 和分母的 6 正好抵消,所以 C(8,3) = 8 × 7 = 56。
第 3 题:12 人的班级,每两人握一次手,一共握多少次? C(12,2) = 12 × 11 ÷ 2 = 66 次。先按人数数:12 × 11 = 132 是「每人的次数」之和,每次握手被数了两遍,÷ 2 = 66。
第 4 题(加餐):8 人乒乓球单循环赛(每两人打一局),一共多少局?如果每人还要和其余每人各打两局,一共多少局? 每对一局 → C(8,2) = 8 × 7 ÷ 2 = 28 局;每对两局 → 28 × 2 = 56 局。第二问也可以按人数算:8 人 × 每人 7 个对手 × 2 局 = 112,再 ÷ 2 = 56(每局被双方各数一遍)。
🎯 一句话记住:组合 = 只看选谁,不看顺序;先排后除:C(n,k) = A(n,k) ÷ k!;「每两人一次」的问题(握手、比赛、配对)= C(n,2) = n×(n−1)÷2。