套路

把相邻间隔取作变量

从一列数里按大小取出几个,改用「首项左边空几个、相邻两项之间空几个、末项右边空几个」当变量;取法与一组非负整数解一一对应,「不相邻」就变成「某个间隔 ⩾1\geqslant1」,几类情形可以用同一个动作一次全数清。

解题套路

从 1,2,…,n1,2,\dots,n 里取 kk 个数,记从小到大是 a1<a2<⋯<aka_1<a_2<\cdots<a_k。换一组变量:

u0=a1−1,ui=ai+1−ai−1 (1⩽i⩽k−1),uk=n−ak.u_0=a_1-1,\quad u_i=a_{i+1}-a_i-1\ (1\leqslant i\leqslant k-1),\quad u_k=n-a_k .

它们全部 ⩾0\geqslant0,而且

u0+u1+⋯+uk=n−k.u_0+u_1+\cdots+u_k=n-k .

这是一一对应:给一组非负整数解,令 a1=u0+1a_1=u_0+1、ai+1=ai+ui+1a_{i+1}=a_i+u_i+1 就还原出唯一一个取法。于是

「取 kk 个数」的方案数 == 方程 u0+⋯+uk=n−ku_0+\cdots+u_k=n-k 的非负整数解个数 =Cnk=C_{n}^{k},

隔板法算出来的正是 C(n−k)+kk=CnkC_{(n-k)+k}^{k}=C_n^k——先用这条自洽检查确认换元没写错,再往下用。

关键在于,条件全都翻译成了对 uiu_i 的下界:

原来的说法换元之后
aia_i 与 ai+1a_{i+1} 相邻ui=0u_i=0
aia_i 与 ai+1a_{i+1} 不相邻ui⩾1u_i\geqslant1
两两不相邻u1,…,uk−1u_1,\dots,u_{k-1} 全 ⩾1\geqslant1
首项不取 11u0⩾1u_0\geqslant1

下界一律用「预扣」消掉:要求 ui⩾1u_i\geqslant1 就令 ui′=ui−1u_i'=u_i-1,右端的总量相应减 11,方程重新变成一个纯粹的非负整数解问题。

用起来是什么样

从 1∼91\sim9 里取 33 个数(n=9n=9、k=3k=3),u0+u1+u2+u3=6u_0+u_1+u_2+u_3=6:

  • 两两不相邻(u1,u2⩾1u_1,u_2\geqslant1):预扣两个,u0+u1′+u2′+u3=4u_0+u_1'+u_2'+u_3=4,解数 C4+33=C73=35C_{4+3}^{3}=C_7^3=35。
  • 三个连号(u1=u2=0u_1=u_2=0):u0+u3=6u_0+u_3=6,解数 C6+11=7C_{6+1}^{1}=7。
  • 恰有一处相邻(u1u_1、u2u_2 恰有一个为 00):两支对称,每支 u0+u′+u3=5u_0+u'+u_3=5,解数 C5+22=21C_{5+2}^{2}=21,共 4242。

三堆加起来 35+7+42=84=C9335+7+42=84=C_9^3 ✓——同一个动作做三遍,而不是三种互不相干的技巧。

什么时候想到它

  • 条件是相邻 / 不相邻 / 间隔至少几个这一类(它们全是对 uiu_i 的下界);
  • 要的不是一个数,而是按「有几处相邻」分类的整张表——正面数要分好几类,换元之后是同一套动作;
  • 插空法只回答「两两不相邻有几种」,这条路把「恰好有几处相邻」也一并回答了。

边界

  • 只对「从一列里按大小取」有效。 取出来还要排顺序的,另乘 AkkA_k^k;元素本身有区别(不是位置)的,这条换元无从谈起。
  • 两端的 u0u_0、uku_k 与中间的 uiu_i 意义不同:中间那些管相邻,两端那两个只管靠不靠边。别把两端也顺手加上 ⩾1\geqslant1。
  • 换元后先做一次自洽检查(无约束时解数必须等于 CnkC_n^k)。这一步花不了几秒,却能挡住「右端写成 n−k+1n-k+1」这种最常见的手滑。

学它之前先会

共 1 条前置、最深 1 层。

共 1 道题考到本条。