题意
- 给你一个 3 × n \rm 3 \times n 3×n的棋盘,棋盘上有一些棋子,问有多少种不同填棋子的顺序可以填满棋盘,一个位置可以被填棋子当且仅当它的左右已经填了棋子或者它的上下都填了棋子。( n ≤ 2000 \rm n \le2000 n≤2000)
首先判掉无解的情况,如果第一行或者第三行有连续两个空棋子,或者四个边角没有填棋子,就不存在填满棋盘的方案。
把这个棋盘当做一个四联通图,我们可以发现每个空格组成的联通块是互不影响的,我们可以分联通块DP,再组合一下各个联通块的方案就好了。
对于某个联通块,我们观察到每一列的填法只与上一列的棋子是通过哪种规则填的和填的时间有关,我们记 f ( 0 / 1 , i , j ) \rm f(0/1,i,j) f(0/1,i,j)表示第 2 \rm2 2行第 i \rm i i列的格子是在上下格子填完之后还是左右格子填完之后,是在当前联通块操作序列中第 j \rm j j个操作的方案数,那么分类讨论上一列的格子通过哪种规则填来转移。
记 S i z e \rm Size Size为当前联通块的大小, s u m \rm sum sum为当前列上下的空格子数:
- 如果上一个格子是通过填好上下格子再填的话,这个格子也通过填好上下格子再填,那么这两列是互不影响的。
f ( 0 , i , j ) = ∑ k = 1 S i z e f ( 0 , i − 1 , k ) × A ( j − 1 , s u m ) \rm f(0,i,j)=\sum_{k = 1}^{Size}f(0,i-1,k)\times A(j-1,sum) f(0,i,j)=k=1∑Sizef(0,i−1,k)×A(j−1,sum) - 如果上一个格子是通过填好左右格子再填的话,这个格子必须通过填好上下格子再填,那么当前格子必须先填。
f ( 0 , i , j ) = ∑ k = j − s u m − 1 S i z e f ( 1 , i − 1 , k ) × A ( j − 1 , s u m ) \rm f(0,i,j)=\sum_{k=j-sum-1}^{Size}f(1,i-1,k) \times A(j-1,sum) f(0,i,j)=k=j−sum−1∑Sizef(1,i−1,