P5664 [CSP-S2019] Emiya 家今天的饭
\(\text{solution}\)
这道题还是有点东西的。不知道 puck 当年这道题打了暴力没有。
明显考虑容斥,发现求所有列被选的个数都不大于 \(\frac{k}{2}\) 的有点难算,但是我们可以搞成所有的方案数 \(ans - 1 - b\),\(b\) 为有一个列是大于 \(\frac{k}{2}\) 的方案数,发现最多只能有一个列选的数的个数大于 \(\frac{k}{2}\),所以我们用 DP 去求解这个东西就好了。
考虑枚举每一列,表示当前列选的数的个数大于 \(\frac{k}{2}\),然后设 \(f_{i, j, k}\) 表示前 \(i\) 行,当前列选了 \(j\) 个数,其他列选了 \(k\) 个数的方案数,这个东西很好求,最后用 \(ans\) 减一下就好了。
但是我们考虑这种做法是会炸时间的,考虑我们只关心它们的相对大小,也就是差值,所以我们优化成 \(f_{i, j}\) 为前 \(i\) 行,当前行列选的数的个数与其他列的个数差值为 \(j\) 时的方案数,然后转移就行了。
总方案数就是 \(ans = \prod\limits_{i = 1}^{n}\left(\left(\sum\limits_{j = 1}^{m} a_{i, j} \right) + 1 \right) - 1\),为什么要减 \(1\),因为至少要有一道菜。

浙公网安备 33010602011771号