do_while_true

一言(ヒトコト)

一次对计数问题将常用套路形式化剖析的尝试

例题:对于所有 \(i,j\leq n\),求出 \(f_{i,j}\) 表示有多少长度为 \(i\) 的排列 \(a\),前 \(j\) 个位置要满足 \(a_j\neq j\)

回顾一下错排数的递推式是如何求得的?单独拎出最后一个位置 \(n\) 及其代表的数 \(n\),先考虑长度 \((n-1)\) 的错排,讨论将位置 \(n\) 以及数 \(n\) 插入时不同方式的方案数之和。

尝试对这个方法进行抽象化:

对一个满足一些条件的组合对象进行计数时,想要通过规模更小的问题的答案来获得当前问题答案,考虑去除组合对象中的若干元素,然后考虑将这些元素在规模更小的组合对象中插入后,方案数之和是多少。

能否沿用这个思路解决例题?

方法一:考虑将一个限制不能冲突的位置及其代表的数加入,首先考虑这个数放入了前面哪个位置。

第一种情况是放入一个有限制的位置,有 \((j-1)\) 种放法。放入之后剩下一个单独的随便放的数,和一个单独的随便放的位置。把这两个看作同一个编号,那么就化为了 \((i-1)\) 个数及位置,有 \((j-2)\) 个限制的情况。

第二种情况是放入一个无限制的位置,有 \((i-j)\) 种放法。放入之后同理可以将单独的数和单独的位置看作同一个编号,就化为了 \((i-1)\) 个数及位置,有 \((j-1)\) 个限制的情况。

所以递推式为 \(f_{i,j}=(j-1)f_{i-1,j-2}+(i-j)f_{i-1,j-1}\)

方法二:考虑将一个无限制的位置及数放入。

第一种情况是放入一个有限制的位置,可推得这种情况的方案数 \(jf_{i-1,j-1}\)

第二种情况是放入一个无限制的位置,这种情况的方案数 \((i-j-1)f_{i-1,j}\)

递推式为 \(f_{i,j}=jf_{i-1,j-1}+(i-j-1)f_{i-1,j}\)

值得注意的是 \(i=j\) 时不存在无限制的数,所以需要初始化的是 \(f_{i,i}\)

方法三:考虑将一个有限制的位置及数放入,假装没有限制先任意选 \(f_{i,j-1}\),再容斥掉不合法的情况(强制那个有限制的冲突) \(-f_{i-1,j-1}\)

递推式为 \(f_{i,j}=f_{i,j-1}-f_{i-1,j-1}\)


虽然是经典思路,但是需要总结,而总结就需要一些比较抽象的描述,但是抽象的描述又离不开题目否则难以理解。

一次尝试,暂且一记,是否有时间有意愿去整理另论。

posted @ 2022-08-31 22:00  do_while_true  阅读(70)  评论(0编辑  收藏  举报