【Luogu P1350】车的放置
链接:
题目大意:
给定一个畸形的方块,求在上面放 \(k\) 个车能让它们互不相吃的方案数。
正文:
我们知道,车能够吃掉它这一行和一列的棋子,先来处理吃一行的情况。其实这个特别简单,在枚举的时候每一行只算一个棋子的就好了。
再处理列的情况。我们设 \(f_{i,j}\) 表示 \(i\) 行里一共有 \(j\) 个车的方案数。每次处理时,第 \(i\) 行就是第 \(i-1\) 行的方案数乘上这一行还可以放的位置个数。那么这个位置个数是什么呢?因为前 \(i-1\) 行放了 \(j-1\) 互不相吃的棋子(也就是每列只有一个车),那如果我们还要在第 \(i\) 行放一个,它就只能放在剩下的位置,也就是 \(m - (j - 1)\) 个位置,其中的 \(m\) 表示第 \(i\) 行的格子个数。
也就是说转移方程为:
\[f_{i,j}=f_{i-1,j-1}\times (m-j+1)+f_{i-1,j}
\]
后面还加个 \(f_{i-1,j}\) 是因为第 \(i\) 行还可以不放任何车。
代码:
for (int i = 0; i <= b + d; i++) f[i][0] = 1;
for (int i = 1; i <= b + d; i++)
{
for (int j = 1; j <= k; j++)
{
if (i <= b && j > a) break;
f[i][j] += f[i - 1][j];
if (i <= b) (f[i][j] += f[i - 1][j - 1] * (a - j + 1) % mod) %= mod;
else (f[i][j] += f[i - 1][j - 1] * (a + c - j + 1) % mod) %= mod;
}
}
printf("%d\n", f[b + d][k]);