📅  最后修改于: 2023-12-03 15:07:36.731000             🧑  作者: Mango
这个问题可以看成是一道组合问题。我们需要计算在 3 x N 的网格中绘制 K 个单元格的方案数,且要求任意连续的 P 列中都不能有未绘制的单元格。
假设用 f(n, m) 表示在 n x 3 的网格中绘制 m 个单元格的方案数,那么我们需要解决的实际上是 f(3N, K) 减去 f(3N, P-1)。
接下来我们考虑如何计算 f(n, m)。
首先,我们可以将 n x 3 的网格表示成一个由 n 个 3 x 1 的列构成的网格。对于一个 3 x 1 的列,它最多有 8 种状态,其中 5 种状态画一个单元格,3 种状态不画单元格。我们可以用状态转移方程计算出 f(n, m):
f(n, m) = ∑ f(n-1, m-k)
其中 ∑ 是对所有 k 满足 $0 \leq k \leq 5$ 且 $k \leq m$ 的取值求和。这里的思路是,假设我们在第 n 列画了 k 个单元格,那么前 n-1 列需要画 m-k 个单元格。因此我们可以枚举第 n 列画 k 个单元格的情况,并将剩余的 m-k 个单元格分配给前 n-1 列。
接下来,我们考虑如何应用限制条件。如果我们直接套用上述状态转移方程,会算出一些无效状态,这些状态有一列或多列未绘制单元格,违反了限制条件。因此,我们需要在状态转移中加入限制条件。
一种方法是在状态转移中引入附加维度,用 f(n, m, p) 表示在 n x 3 的网格中绘制 m 个单元格,且最后 p 列连续且所有连续列的长度都小于 P 的方案数。这样,我们就可以在状态转移中考虑最后加进来的一列的连续性了:
f(n, m, p) = ∑ f(n-1, m-k, (p+1)%P), 0 ≤ k ≤ 5 ∧ k ≤ m, p < P
其中 (p+1)%P 表示如果加入了一列后刚好形成了一个连续列,则 p+1=0,否则 p+1=p+1。
不难想到,要求没有 P 个连续的列未绘制,其实就是要求 f(3N, P-1) = 0。因此,我们可以通过这个限制条件来计算最终的答案:
result = f(3N, K) - f(3N, P-1)
参考实现(Python):