给定两个数 n , m n,m n,m,请你求出存在多少个大小为 n × m n \times m n×m的矩阵 A A A满足:
① 0 ≤ A i , j ≤ m , A i , j ∈ N 0\le A_{i,j} \le m, A_{i,j} \in N 0≤Ai,j≤m,Ai,j∈N
② A i , j < A i , j + 1 A_{i,j}
③ A i , j < A i − 1 , j + 1 A_{i,j}
请将答案对 1 0 9 + 7 10^9+7 109+7取模。
每一行的数从左到右一定是递增的,且在 [ 0 , m ] [0,m] [0,m]中的自然数恰有 1 1 1个未出现在此行中。
根据引理,我们考虑 d p dp dp。
d p i , j dp_{i,j} dpi,j: 在第 i i i行中没有出现 j ( 0 ≤ j ≤ m ) j(0 \le j \le m) j(0≤j≤m)的方案数(对于前 i i i行)
根据限制, d p i , j dp_{i,j} dpi,j的合法转移点为 d p i − 1 , p ( 0 ≤ p ≤ j + 1 ) dp_{i-1,p}(0 \le p \le j+1) dpi−1,p(0≤p≤j+1),所以状态转移为 d p i , j = ∑ p = 0 j + 1 d p i − 1 , p dp_{i,j}=\sum_{p=0}^{j+1} dp_{i-1,p} dpi,j=p=0∑j+1dpi−1,p
经过一个简单的转化,得到 d p i , j = d p i , j − 1 + d p i − 1 , j + 1 dp_{i,j}=dp_{i,j-1}+dp_{i-1,j+1} dpi,j=dpi,j−1+dpi−1,j+1。
直接暴力转移是 O ( n m ) O(nm) O(nm)的,需要优化。
由于状态本身已经爆炸,所以我们需要考虑一种特殊的方式来优化。考虑赋予这个 d p dp dp一个实际意义,然后转而思考这个实际意义的答案。
在说正解之前,我们先来一波怀旧。当年我们学习组合数问题的时候,遇到过这样的一个问题: 小明在一个 n × m n \times m n×m的矩阵的左下角,他要往右上角走,每一步可以向上或向下,求方案数。这就是一个 d p i , j = d p i , j − 1 + d p i − 1 , j dp_{i,j}=dp_{i,j-1}+dp_{i-1,j} dpi,j=dpi,j−1+dpi−1,j的实际意义。赋予了这个实际意义之后,答案就变成了一个简单的组合数的形式,从而可以快速计算。
之所以要插叙这一段,是因为我们可以根据这个例子来构造本题的一个实际意义。对于一个 n × m n \times m n×m的矩阵, d p i , j − 1 dp_{i,j-1} dpi,j−1就相当于从左边往右边走, d p i − 1 , j + 1 dp_{i-1,j+1} dpi−1,j+1相当于从右上往左下走;同时,对于每一行的第一个位置 d p i , 0 dp_{i,0} dpi,0相当于从上往下走。
我们似乎很难思考这个图的组合意义。不慌,我们把难看的斜着走的部分给去掉,方式为将上图中的第 i i i行向右平移 i − 1 i-1 i−1格,得到:
(图依然是盗的)
仔细观察这个图,不难发现: 问题等价于从起点走到终点,只能向终点的方先走,且不能走上任何一条黑线的方案数!
最后我们将这个图给大力翻转一下(如下图),图中左下角为 ( 0 , 0 ) (0,0) (0,0),右上角为 ( n + m − 1 , n ) (n+m-1,n) (n+m−1,n)。现在,我们开始正式思考这个实际意义下的答案。
令左边的线为 A A A,右边的线为 B B B。
一种初步的做法是: 求出从起点到终点的总方案数 t o t tot tot(即不考虑“不能走过粗线”的限制),然后减去经过左边一条粗线的方案数,再减去经过右边一条粗线的方案数。我们可以在线上枚举一个点 P P P,求出 f ( A , P ) × f ( P , B ) f(A,P) \times f(P,B) f(A,P)×f(P,B)之和 s u m sum sum(即从 A A A到 P P P,只能向上或向右走的方案数),答案为 t o t − s u m tot-sum tot−sum。
很可惜这个做法大量重复扣去了一些不合法的方案,并没有正确性。但是,这启发我们去容斥地计算答案。
令仅包含A, B的字符串 S S S表示了一种方案。更具体的, S = A A B B A A S=AABBAA S=AABBAA表示先两次经过A,又两次经过B,最后又两次经过A并到达终点的方案。为了方便思考,我们将 S S S给简化为一个相同两个字母不同的串 S ′ S' S′。如 S = A A B B A A S=AABBAA S=AABBAA被简化为了 S ′ = A B A S'=ABA S′=ABA。不难发现,从起点到终点的所有走法,无论是否合法都对应着唯一的一个字符串 S S S。
那么所有不合法的方案就是:
(1)A
(2)B
(3)AB
(4)BA
(5)ABA
(6)BAB
⋯ ⋯ \cdots \cdots ⋯⋯
我们要减去所有以A结尾的字符串,加上所有以BA结尾的字符串,再减去ABA,再加上BABA ⋯ \cdots ⋯另外一遍,我们减去所有以B结尾的字符串,加上所有以AB结尾的字符串,再减去BAB,加上ABAB ⋯ \cdots ⋯
此时所有不合法的字符串都被恰好算了一次。
现在,我们的关键在于如何求出某个后缀为 S ′ ′ S'' S′′的方案数量。我们可以巧妙运用翻折,如下图:
S ′ S' S′是关于 S S S关于直线 B B B的对称点。
综上所述,我们可以采用“轮流翻折”的方式来计算。设当前点 P P P为终点,我们先将它沿 A A A翻折,再沿 B B B,再沿 A A A……逐一计算逐一加/减即可。
时间复杂度 O ( n + m ) O(n+m) O(n+m)。
d p dp dp是可以带入实际意义的。
本题将得到的图进行了多步转化,使得实际意义越发清晰。最后,我们吸收了错误的解法的思想,果断容斥+巧用翻折转化,最终解决了本题。
绝世好题。