📅  最后修改于: 2023-12-03 15:41:15.892000             🧑  作者: Mango
给定一个 $3×N$ 的网格和整数 $K$ 和 $P$,求绘制 $K$ 个长度为 $3$ 的不同列,使得每连续的 $P$ 个列中都至少存在一个列不被绘制的方法数量。
这道题可以使用动态规划来解决。
首先,我们定义 $dp[i][j][k]$ 表示绘制到第 $i$ 列,其中已经绘制了 $j$ 个长度为 $3$ 的不同列,且最后一个绘制的是第 $k$ 列的方案数。我们可以利用状态转移方程来求解:
$$ dp[i][j][k] = \sum_{c=1}^{3} dp[i-1][j-(c==k)][c] $$
意思是:第 $i$ 列有三种可能的绘制方法,即和第 $k$ 列的绘制方法不同,和第 $k$ 列的绘制方法相同但是与上一列的绘制方法不同,和上一列的绘制方法相同。我们只需要枚举 $c$,然后将所以可能的情况相加起来就可以了。
下一步是判断限制条件:每连续的 $P$ 个列中必须有至少一列没有被绘制。在计算 $dp[i][j][k]$ 的时候,我们需要同时记录第 $i-P$ 列到第 $i-1$ 列中被绘制的列的编号 $l$,如果 $j-l<P$,且第 $k$ 列恰好等于其中一列的编号,那么这个状态就不能被转移。
具体来说,可以再开一个一维数组 $last$,其中 $last[s]$ 表示编号为 $s$ 的列在 $(i-P,i-1)$ 区间内最后一次被绘制的位置。如果这个列在区间内没有被绘制过,令 $last[s]=-1$。
我们只需要在状态转移方程中加入判断即可:
$$ dp[i][j][k] = \sum_{c=1}^{3} [k≠c] \cdot dp[i-1][j-(c==k)][c] \cdot [l < i-P \textrm{ 或 } j-l<P \textrm{ 或 } c≠ k] $$
def count_ways(n, k, p):
dp = [[[0] * 4 for _ in range(k+1)] for _ in range(n+1)]
last = [-1] * 4
dp[0][0][0] = 1
for i in range(1, n+1):
for j in range(k+1):
for k in range(1, 4):
s = j-(k==last[k])
if s>=0 and s<p:
dp[i][j][k] = 0
else:
dp[i][j][k] = sum(dp[i-1][s+(c==k)][c] for c in range(1, 4) if j-(c==last[c])>=p)
dp[i][j][k] %= 998244353
last[k] = i if dp[i][j][k]>0 else last[k]
ans = sum(dp[n][k][i] for i in range(1, 4))
return ans % 998244353
其中 n
、k
、p
分别表示网格的列数、需要绘制多少列、每连续多少列必须有一列没有被绘制,函数返回的结果即为所有符合要求的绘制方案数量。此外,这段代码的时间复杂度为 $O(nkp)$,空间复杂度为 $O(nk)$。