题解:CF1237F Balanced Domino Placements
下文用
从特殊到一般
想一想,如果只能竖着放骨牌,有多少种方案?
设初始有
- 有
\textit{emptyC} 列可以竖着放骨牌,从中选i 列的排列数,即P_{\textit{emptyC}}^{i} 。 - 有
n 行,其中某些行不能放骨牌(因为初始已经放了骨牌),从中选择i 个连续两行(用来竖着放骨牌)的方案数。
由于第一个问题只和列有关,第二个问题只和行有关,所以两个问题互相独立,根据乘法原理,可以分别计算再相乘。
第一个问题
为什么要计算的是排列数,而不是组合数?
假如可以:
- 在第
1 列的第1,2 行竖着放一个骨牌。 - 在第
2 列的第3,4 行竖着放一个骨牌。 - 在第
3 列的第5,6 行竖着放一个骨牌。
根据题目约束,这
- 在第
1 列的第3,4 行竖着放一个骨牌。 - 在第
2 列的第5,6 行竖着放一个骨牌。 - 在第
3 列的第1,2 行竖着放一个骨牌。
也就是说,只要我能竖着放
第二个问题
这可以用 DP 解决。
定义
考虑选或不选,有
其中
初始值
有
回到原问题
假设我们已经把
但是,如果横着放
设初始有
枚举竖着放恰好
- 有
\textit{emptyC}-2j 列可以竖着放骨牌,从中选i 列的排列数,即P_{\textit{emptyC}-2j}^{i} 。 - 有
\textit{emptyR}-2i 行可以横着放骨牌,从中选j 行的排列数,即P_{\textit{emptyR}-2i}^{j} 。 - 有
n 行,其中某些行不能放骨牌,从中选择i 个连续两行(用来竖着放骨牌)的方案数。 - 有
m 列,其中某些列不能放骨牌,从中选择j 个连续两列(用来横着放骨牌)的方案数。
和
上述四个问题的方案数相乘,即
枚举
AC 代码(Golang)
package main
import . "fmt"
func main() {
const mod = 998244353
const mx = 3600
pow := func(x, n int) int {
res := 1
for ; n > 0; n /= 2 {
if n%2 > 0 {
res = res * x % mod
}
x = x * x % mod
}
return res
}
F := [mx + 1]int{1}
for i := 1; i <= mx; i++ {
F[i] = F[i-1] * i % mod
}
invF := [...]int{mx: pow(F[mx], mod-2)}
for i := mx; i > 0; i-- {
invF[i-1] = invF[i] * i % mod
}
perm := func(n, k int) int {
return F[n] * invF[n-k] % mod
}
var n, m, k, r1, c1, r2, c2, ans int
Scan(&n, &m, &k)
banR := make([]bool, n)
banC := make([]bool, m)
for ; k > 0; k-- {
Scan(&r1, &c1, &r2, &c2)
banR[r1-1] = true
banR[r2-1] = true
banC[c1-1] = true
banC[c2-1] = true
}
calc := func(ban []bool) ([]int, int) {
n := len(ban)
f := make([][]int, n+1)
for i := range f {
f[i] = make([]int, n/2+1)
f[i][0] = 1
}
for i := 1; i < n; i++ {
for j := 1; j <= (i+1)/2; j++ {
f[i+1][j] = f[i][j]
if !ban[i] && !ban[i-1] {
f[i+1][j] = (f[i+1][j] + f[i-1][j-1]) % mod
}
}
}
empty := 0
for _, b := range ban {
if !b {
empty++
}
}
return f[n], empty
}
f, emptyR := calc(banR)
g, emptyC := calc(banC)
for i, v := range f { // i 个竖放
for j, w := range g { // j 个横放
if j > emptyR-i*2 || i > emptyC-j*2 {
break
}
ans = (ans + v*w%mod*perm(emptyC-j*2, i)%mod*perm(emptyR-i*2, j)) % mod
}
}
Print(ans)
}
欢迎关注 B站@灵茶山艾府