[luogu]P2051 [AHOI2009]中国象棋

原题链接:P2051 [AHOI2009]中国象棋

题意

炮能隔一个棋子打人,求一个棋盘上放置炮的合法方案数(炮不互相攻击)。

分析

既然求方案数那应该就是dp(神仙言论),以前做过很多类似的状压DP,这个题很直观的三进制状压啊。。

看看范围。。。

$n/le 100$。溜了溜了此题无解

理性分析一波,发现一行一列最多放三个炮(废话),那么状态设计就挺简单了。

首先肯定是按行地推。

我们发现如果两列放置的棋子是一样的,那么我们不管放哪列,对其他列的影响都是一样的。

那么我们就不用管具体哪一列了,我们只需要把已经放置的棋子数为0,1,2的列的个数统计出来作为状态,方案数作为状态值就可以了。

对于一个新列上面$(0,1,2)$个的列分别有$(i,j,k)$列,我们

如果不放置棋子,就直接等于上一行$(i,j,k)$的方案数。

如果只放一个棋子,就直接等于上一行$f(i+1,j-1,k)*(i+1)$或上一行$f(i,j+1,k-1)*(j+1)$的方案数。

如果两个棋子都放在$0$或都放在$1$列,那么方案数加上上一列$f(i+2,j-2,k)*(i+2)$或者$f(i,j+2,k-2)*(j+2)$。

  如果一个放在$0$一个放在$1$,那么方案数就加上$f(i+1,j,k-1)*((i+1)*j)$(理解下)。

$f[m][i][j][k]$表示第$m$行,$i,j,k$就不说了。

我们发现第一维可以滚掉,第三维可以计算得出,可以直接删掉。

那么数组也很小了。

原文地址:https://www.cnblogs.com/onglublog/p/10547279.html