CF198C (题号好像错了) 排列小trick
有一个长度为n的排列a,其中有一些位置被替换成了−1。你需要尝试恢 复这个排列,将−1替换回数字。 求有多少种可行的替换方法,满足得到的是一个排列,且不存在ai = i的 位置。n ≤ 2000。
对于一个排列,可以用一个n*n的方阵来表示,第i行第j列如果被标记,则代表数字 i填在了第j个位置(aj = i)
对于给定的排列,不为−1的位置已经被 标记在棋盘上,而棋盘的主对角线上(ai = i)不可以被标记
从棋盘中删去不为−1的位置的列,以及已经出现了的数字的行,记此时棋盘大小为N
不难发现,每列不可被标记的位置至多只有1个,每行也是同样,记这种位置的数量为M
令f[N,M]表示,在这样的棋盘上标记N个格子的方案数
转移方程为:f[n,m] = f[n,m − 1] − f[n − 1,m − 1] 边界为f[i,0] = i!
转移方程的含义为,相比起f[n,m − 1]的状态,f[n,m]的状态要多一个不 可标记的位置,而标记了这个位置的方案数为f[n − 1,m − 1](有一行一列已经被占用),因此从中减去。