- bitworld 的博客
【CSP-J初赛】排列组合二十个题型
- 2025-7-31 16:44:11 @
排列组合二十个题型
一、两大基本原理
所有复杂的组合计数问题,都可以回归到两个最基本的原理:加法原理和乘法原理。
1. 加法原理 (Rule of Sum)
如果完成一件事情有 类方法,在第一类方法中有 种不同的方式,在第二类方法中有 种不同的方式,……,在第 类方法中有 种不同的方式,那么完成这件事情共有 种不同的方式。
核心:分类。各类方法之间相互独立,任何一种方法都可以独立完成事件。
示例:从北京到上海,可以乘飞机(3个航班)、乘高铁(5个车次)、乘普速火车(2个车次)。那么从北京到上海共有 种不同的旅行方式。
2. 乘法原理 (Rule of Product)
如果完成一件事情需要分成 个步骤,完成第一个步骤有 种不同的方式,完成第二个步骤有 种不同的方式,……,完成第 个步骤有 种不同的方式,那么完成这件事情共有 种不同的方式。
核心:分步。各个步骤缺一不可,必须依次完成所有步骤才能完成整个事件。
示例:从上衣(3件不同)、裤子(4条不同)、鞋子(2双不同)中各选一件搭配。总搭配方案数为 种。
二、排列与组合的核心定义
1. 排列 (Permutation)
从 个不同元素中,取出 () 个元素,并按照一定的顺序排成一列,这个过程称为排列。排列数用 (或 ) 表示。
计算公式:
$$A_n^m = n(n-1)(n-2)\cdots(n-m+1) = \frac{n!}{(n-m)!} $$当 时,称为全排列,记作 。
核心:有序。元素的顺序会影响结果。例如,(A, B)
和 (B, A)
是两种不同的排列。
2. 组合 (Combination)
从 个不同元素中,取出 () 个元素,不考虑顺序地并成一组,这个过程称为组合。组合数用 (或 ) 表示。
计算公式:
核心:无序。元素的顺序不影响结果。例如,{A, B}
和 {B, A}
是同一个组合。
组合数的两个重要性质:
- (从n个里选m个,等于从n个里不选n-m个)
- (杨辉三角/帕斯卡恒等式)
三、排列组合问题的20种核心题型
我们将问题分为几大类:基础应用、特殊元素/位置约束、重复元素问题、分组与分配、特殊结构、以及高级计数方法。
A. 基础与约束型
题型1:无约束排列
问题:从5本不同的书中选出3本送给3个不同的人,每人一本,有多少种送法? 方法:相当于从5个元素中选3个进行排列。 计算:。
题型2:无约束组合
问题:从一个有5名男队员和3名女队员的队伍中,选出4人组成一个小组,有多少种选法? 方法:相当于从总共8人中选4人,不考虑顺序。 计算:$C_8^4 = \frac{8 \times 7 \times 6 \times 5}{4 \times 3 \times 2 \times 1} = 70$。
题型3:相邻问题——捆绑法 (Bundling Method)
问题:有A, B, C, D, E五个人排成一队,要求A和B必须站在一起,有多少种排法? 方法:将必须相邻的元素(A, B)看作一个整体"X"。现在问题变成对X, C, D, E四个元素进行全排列。之后,再考虑"X"内部元素的排列。 计算:
- 捆绑:(A,B) 视为一个大元素X。
- 排列外部:对 X, C, D, E 进行全排列,有 种。
- 排列内部:对 (A,B) 内部进行全排列,有 种。
- 总数(乘法原理): 种。
题型4:不相邻问题——插空法 (Insertion Method)
问题:有A, B, C, D, E五个人排成一队,要求A和B不能相邻,有多少种排法? 方法:先排列其他没有限制的元素,然后在它们形成的空隙中插入有不相邻要求的元素。 计算:
- 先排列 C, D, E,有 种。
- C, D, E 排好后,形成4个空隙(包括两端):
_ C _ D _ E _
。 - 将 A, B 插入这4个空隙中,相当于从4个位置选2个给A, B排列,有 种。
- 总数(乘法原理): 种。 另一种思路(正难则反):总排列数减去A,B相邻的排列数。。
题型5:特定位置——优先法 (Priority Method)
问题:用数字0, 1, 2, 3, 4组成没有重复数字的五位数,其中偶数有多少个? 方法:优先考虑有限制条件的元素或位置。 计算:
- 个位有限制(必须是偶数)。但0比较特殊,不能作首位。因此需要分类讨论。
- Case 1:个位是0。
- 个位已定(1种选择)。
- 万位从剩下4个非0数字中选,有4种选择。
- 其余3位从剩下3个数字中全排列,有 种。
- 此情况共 个。
- Case 2:个位是2或4。
- 个位有2种选择(2或4)。
- 万位不能是0且不能是已选的偶数,有3种选择。
- 其余3位从剩下3个数字中全排列,有 种。
- 此情况共 个。
- 总数(加法原理): 个。
题型6:顺序固定——除法模型 (Division Model)
问题:有A, B, C, D, E五个人排成一队,要求A必须在B的左边(不一定相邻),有多少种排法? 方法:对于任意一种排列,A和B的位置关系只有两种可能:A在B左边,或者B在A左边。这两种情况的数目是完全对称的。因此,满足条件的排法占总数的一半。 计算:总排列数为 。A在B左边的排法为 种。 另一种思路:先从5个位置中选2个位置给A和B,有 种。因为A必须在B左边,所以这两个位置上它俩的放法是固定的(1种)。然后,剩下3个元素在剩下3个位置上全排列,有 种。总数 种。
B. 重复元素问题
题型7:有重复元素的全排列
问题:用2个A,3个B,1个C组成一个六位数的字符串,有多少种不同的字符串? 方法:先将所有元素视为不同(如 )进行全排列,然后除以重复元素内部的全排列,以消除因相同元素交换位置而产生的重复计数。 计算:
$$\frac{6!}{2! \cdot 3! \cdot 1!} = \frac{720}{2 \cdot 6 \cdot 1} = 60 $$题型8:可重复选择的组合——隔板法 (Stars and Bars)
问题:有10个相同的糖果,分给3个小朋友,每人至少分到1个,有多少种分法?
方法:将10个糖果排成一排 o o o o o o o o o o
。它们之间形成了9个空隙。要分成3份,只需要在这9个空隙中插入2个“隔板”。
计算:从9个空隙中选择2个位置放隔板,有 种分法。
题型9:隔板法变种(允许为空)
问题:有10个相同的糖果,分给3个小朋友,允许有人分不到,有多少种分法? 方法:先借给每个小朋友1个糖果,这样总共有 个糖果。现在问题转化为,将13个糖果分给3个小朋友,每人至少1个。 计算:13个糖果形成12个空隙,插入2个隔板。有 种分法。 通用公式:将 个相同物品分给 个不同的人(允许为空),方案数为 。
C. 分组与分配问题
题型10:有序分配问题 (Distinguishable items to distinguishable boxes)
问题:将5本不同的书分给3个人,每人至少一本,有多少种分法? 方法:这是个复杂问题,通常使用容斥原理或第二类斯特林数。
- 第二类斯特林数:将5个不同元素分成3个非空集合的方案数,记作 。然后再将这3个集合分配给3个人。
- 。(计算较复杂,见题型12)
- 分配给3个人,有 种方式。
- 总数: 种。
- 容斥原理(见题型18):总方案数(每本书可以给3个人中的任意一个,)减去“至少有一个人没分到”的,加上“至少有两个人没分到”的。
- :指定一个人没分到。
- :指定两个人没分到。
- 总数:$3^5 - C_3^1 \cdot 2^5 + C_3^2 \cdot 1^5 = 243 - 3 \cdot 32 + 3 \cdot 1 = 243 - 96 + 3 = 150$。
题型11:无序分组问题 (Distinguishable items to indistinguishable boxes)
问题:将5本不同的书分成3堆,每堆至少一本,有多少种分法? 方法:这就是第二类斯特林数 (Stirling Numbers of the Second Kind) 的定义。 计算: 的计算可以通过分组情况的枚举:
- 分组为 (3, 1, 1): 先选3本 。 种。
- 分组为 (2, 2, 1): 先选1本 ,再从剩下4本中选2本 ,剩下2本自动成堆。同样,两个(2,2)堆无区别,除以 。 种。
- 总数: 种。
题型12:整数划分问题 (Indistinguishable items to indistinguishable boxes)
问题:将5个相同的苹果分成3堆,允许有空堆,有多少种分法? 方法:这是整数划分问题。即把整数5表示成3个非负整数之和。 计算:通过枚举:
- 5 = 5 + 0 + 0
- 5 = 4 + 1 + 0
- 5 = 3 + 2 + 0
- 5 = 3 + 1 + 1
- 5 = 2 + 2 + 1 总共有5种分法。整数划分没有简单的通用公式,通常用动态规划求解。
D. 特殊结构问题
题型13:环形排列 (Circular Permutation)
问题:5个人围着一张圆桌坐,有多少种不同的坐法? 方法:与直线排列相比,环形排列旋转后相同视为一种。可以先固定一个人不动,剩下的人进行全排列。 计算:固定一个人,剩下4人全排列。 种。 通用公式: 个不同元素的环形排列数是 。
题型14:项链问题(可翻转的环形排列)
问题:用5颗不同颜色的珠子串成一个项链,有多少种不同的串法? 方法:项链除了可以旋转,还可以翻转。大部分情况下,翻转会产生新的不同排列(相对于仅旋转),但对于对称的排列则不会。一个简单的处理方法是,如果排列数大于2,翻转会使得不同的排列数减半。 计算:先按环形排列计算 种。由于5是奇数,不存在对称的排列,所以所有排列都可以两两配对(一个和它翻转后的那个)。所以总数是 种。 注意:这是一种简化模型。严格的解法需要使用伯恩赛德引理或波利亚枚举定理。
题型15:错位排列 (Derangement)
问题:有5封写好的信和5个写好地址的信封,要求每封信都不能装入正确的信封中,有多少种装法? 方法:这是一个经典的错位排列问题,记作 或 。 递推公式:。基础情况 。
- 。
- 。
- 。 通项公式:。
E. 高级计数原理与方法
题型16:二项式定理应用
问题:求 的展开式中 项的系数。 方法:根据二项式定理 。 计算:
- 令 。
- 我们需要 中 的指数是7,y的指数是3。所以 应该匹配 。
- 显然 。该项为 $C_{10}^3 (2x)^{10-3}(-y)^3 = C_{10}^3 (2x)^7 (-y)^3$。
- 系数为 $C_{10}^3 \cdot 2^7 \cdot (-1)^3 = 120 \cdot 128 \cdot (-1) = -15360$。
题型17:卢卡斯定理 (Lucas's Theorem)
问题:计算 。 方法:卢卡斯定理用于计算大组合数模小质数 。它将 和 写成 进制,然后对每一位分别计算组合数再相乘。 ,其中 ,。 计算:
- 。
- 的7进制:。
- 的7进制:。
- $C_{100}^{30} \equiv C_2^0 \cdot C_0^4 \cdot C_2^2 \pmod{7}$。
- , (因为 ), 。
- 。
题型18:容斥原理 (Inclusion-Exclusion Principle)
问题:求1到1000之间不能被5、6、8中任意一个整除的数的个数。 方法:总数 - (能被5整除的) - (能被6整除的) - (能被8整除的) + (能被5和6整除的) + (能被5和8整除的) + (能被6和8整除的) - (能被5、6、8都整除的)。 计算:
- 。
- 。
- 。
- 。
- $|A_{5,6}| = \lfloor 1000/\text{lcm}(5,6) \rfloor = \lfloor 1000/30 \rfloor = 33$。
- $|A_{5,8}| = \lfloor 1000/\text{lcm}(5,8) \rfloor = \lfloor 1000/40 \rfloor = 25$。
- $|A_{6,8}| = \lfloor 1000/\text{lcm}(6,8) \rfloor = \lfloor 1000/24 \rfloor = 41$。
- $|A_{5,6,8}| = \lfloor 1000/\text{lcm}(5,6,8) \rfloor = \lfloor 1000/120 \rfloor = 8$。
- 结果: $1000 - (200+166+125) + (33+25+41) - 8 = 1000 - 491 + 99 - 8 = 600$。
题型19:卡特兰数 (Catalan Numbers)
问题:一个栈(先进后出)的进栈序列为1, 2, 3, ..., n,有多少个不同的出栈序列? 方法:这是卡特兰数的经典应用之一。其他应用包括:个节点的二叉树形态数、凸边形三角剖分数、 格网上从左下到右上不穿过对角线的路径数等。 公式:
$$C_n = \frac{1}{n+1} C_{2n}^n = \frac{C_{2n}^n - C_{2n}^{n-1}}{1} $$计算:对于 ,出栈序列数是 。
题型20:动态规划计数 (DP for Counting)
问题:在一个 的网格中,从左上角走到右下角,每次只能向右或向下走,有多少种不同的路径? 方法:虽然这题有组合公式 ,但其思想是DP的。更复杂的情况(如网格中有障碍物)必须用DP。 DP模型:
- 状态: 表示从左上角 走到 的路径数。
- 转移方程:要到达 ,只能从 向下或 向右。所以 。
- 初始化:, 。
- 答案:。
四、练习
A. 选择题
-
将4个不同的小球放入3个不同的盒子,且不允许盒子为空,共有多少种方法? A. B. C. D.
-
5对夫妇参加晚会,从中选出4个人组成一个小组,要求这4个人中不能有任何一对夫妇,有多少种选法? A. B. C. D.
-
计算 的值是? A. 10! B. 100 C. 1024 D. 512
答案与解析:
- C. 这是“有序分配问题”(题型10),也叫“满射”计数。将4个不同物品分成3个非空组(),再将这3组分配给3个不同盒子()。
- B. 分步解决:第一步,从5对夫妇中选出4对,有 种选法。第二步,从选出的每一对夫妇中各选一人,每对都有2种选择,共 种选法。总数 。
- C. 根据二项式定理,$(1+1)^{10} = \sum_{k=0}^{10} C_{10}^k \cdot 1^k \cdot 1^{10-k} = \sum_{k=0}^{10} C_{10}^k$。所以结果是 。
B. 程序代码题
问题:计算组合数模大质数 题意概括:给定 ,计算 的值。 是一个大质数。 核心思路:。除法在模运算中用乘以逆元来代替。根据费马小定理,当 为质数时,。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
ll p; // 模数
// 快速幂计算 (a^b) % p
ll qpow(ll a, ll b) {
ll res = 1;
a %= p;
while (b) {
if (b & 1) res = (res * a) % p;
a = (a * a) % p;
b >>= 1;
}
return res;
}
// 计算 a 在模 p 下的逆元
ll inv(ll a) {
return qpow(a, p - 2);
}
// 计算组合数 C(n, m) % p
ll C(ll n, ll m) {
if (m > n) return 0;
if (m == 0 || m == n) return 1;
if (m > n / 2) m = n - m;
ll num = 1, den = 1;
// 计算分子 n * (n-1) * ... * (n-m+1)
for (ll i = 0; i < m; ++i) {
num = (num * (n - i)) % p;
}
// 计算分母 m!
for (ll i = 1; i <= m; ++i) {
den = (den * i) % p;
}
// 结果 = 分子 * 分母的逆元
return (num * inv(den)) % p;
}
int main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
ll n, m;
cin >> n >> m >> p;
cout << C(n, m) << endl;
return 0;
}
- 复杂度分析:
- 时间复杂度: 。计算分子分母需要 ,求逆元用快速幂需要 。
- 空间复杂度: 。
- 优化:如果需要多次计算组合数,可以预处理 到 的阶乘和阶乘的逆元,将单次查询复杂度降至 (预处理复杂度为 )。