1. 先说清楚:这道“排队”到底卡在哪里
P3223 [HNOI2012] 排队,很多人第一次见到它是在洛谷的组合数学题单里。题面很短:n 个男同学、m 个女同学和两个老师要排成一队,要求任意两个女同学不能相邻,任意两个老师也不能相邻,问一共有多少种排法。
看到“不能相邻”四个字,第一反应基本都是插空法。男生之间没有限制,先排男生,再把有限制的女生和老师往空里插。这个方向是对的,但这道题恶心就恶心在:女生和老师不是同一个“限制集合”。
女生不能挨着女生,老师不能挨着老师,但是老师挨着女生或者女生挨着老师,都是允许的。很多人第一次做这题,会把女生和老师当成同一类“不能相邻的元素”处理,结果要么少算,要么多算。我来完整走一遍推导,把最容易漏掉的那个坑单拎出来讲清楚。
如果你正在刷省选级别的组合计数,或者想练习高精度与计数公式结合的老题,这篇应该能帮你省下不少绕弯的时间。下面所有公式,最后都对应可运行的 C++ 高精度代码,照抄也能过。
题目来源是 2012 年湖南省选,原题标准很高,答案不取模,数字大到必须自己写高精度。这意味着一件事:推导只要错一步,你连“答案对不对”都很难用肉眼判断。所以搞懂每个乘法的来历,比背一个公式重要得多。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 一眼看上去像插空,但它比普通插空多了一个分类
2.1 先界定“合法”的边界,不然后面全是糊涂账
为了不绕晕,我先规定字母含义:
- 男生之间没有约束,随便相邻;
- 任取两个女生,不能相邻;
- 两个老师,不能相邻;
- 老师和女生之间,没有额外限制。
先用手算小例子感受合法和不合法。设 n = 1,m = 1,也就是 1 个男生 M,1 个女生 F,两个
