📌  相关文章
📜  门| Sudo GATE 2020 Mock II(2019年1月10日)|问题6(1)

📅  最后修改于: 2023-12-03 14:58:33.362000             🧑  作者: Mango

门| Sudo GATE 2020 Mock II(2019年1月10日)|问题6

这道问题主要考察图论和动态规划两个知识点。

问题解析

首先,我们需要将题目转换成图的形式,其中门拆分成两个节点,每个节点表示门的一边。例如,对于样例输入:

4
0 3 3 6 4
2 0 1 3 2
1 3 0 1 2
4 6 1 0 3
3 2 2 3 0

我们可以得到如下的图:

```mermaid
graph TD;
    START((start)) -- 0 --> A1((a1));
    START((start)) -- 2 --> A2((a2));
    A1((a1)) -- 3 --> B1((b1));
    B1((b1)) -- 3 --> A3((a3));
    A3((a3)) -- 6 --> END((end));
    A2((a2)) -- 1 --> B2((b2));
    B2((b2)) -- 3 --> A3((a3));
    A3((a3)) -- 2 --> END((end));

其中,每个节点的标号如下:

  • start: 起点
  • end: 终点
  • a1: 门a,左侧节点
  • a2: 门a,右侧节点
  • a3: 门a的中间节点
  • b1: 门b,左侧节点
  • b2: 门b,右侧节点
  • b3: 门b的中间节点

我们可以用动态规划来解决这道问题。为了方便代码实现,我们可以将题目转化成求从起点到终点的最长路径,即为我们需要的答案。

设$dp[i][j][0/1]$为从起点到位置$(i, j)$的最长路径。其中,0表示当前点可以选择门a,1表示当前点可以选择门b。

状态转移方程:

$$ dp[i][j][0]=max{dp[i-1][j][0/1],dp[i][j-1][0/1]}+map[i][j][0] $$

$$ dp[i][j][1]=max{dp[i-1][j][0/1],dp[i][j-1][0/1]}+map[i][j][1] $$

其中,$map[i][j][0/1]$表示从点$(i, j)$出发,到达相邻门的最大值。

边界条件:

$$ dp[1][1][0/1]=map[1][1][0/1] $$

最终,从起点到终点的最长路径即为:$max{dp[n][m][0],dp[n][m][1]}$。

算法实现

下面是python的伪代码实现:

n, m = map(int, input().split())
a = []
for i in range(n):
    a.append(list(map(int, input().split())))

# 构建图
graph = {}
graph[(0,0)] = [(0,1),(1,0)]
graph[(0,1)] = [(0,0),(1,1),(0,2)]
graph[(0,2)] = [(0,1),(1,2)]
graph[(1,0)] = [(0,0),(2,0),(1,1)]
graph[(1,1)] = [(0,1),(1,0),(1,2),(2,1)]
graph[(1,2)] = [(0,2),(2,2),(1,1)]
graph[(2,0)] = [(1,0),(2,1)]
graph[(2,1)] = [(1,1),(2,0),(2,2)]
graph[(2,2)] = [(1,2),(2,1)]

# 动态规划
dp = [[[0]*2 for _ in range(m+1)] for _ in range(n+1)]
dp[1][1][0] = a[0][0]
dp[1][1][1] = a[0][0]

for i in range(1, n+1):
    for j in range(1, m+1):
        dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j][1], dp[i][j-1][0], dp[i][j-1][1]) + a[i-1][j-1] if (i, j) in graph else float('-inf')
        dp[i][j][1] = max(dp[i-1][j][0], dp[i-1][j][1], dp[i][j-1][0], dp[i][j-1][1]) + a[i-1][j-1] if (i, j) in graph else float('-inf')

print(max(dp[n][m][0], dp[n][m][1]))

其中,a表示图中的权重,graph表示邻接表,dp包含所有状态的列表。dp[i][j][0]表示从起点到位置$(i, j)$的最长路径,其中,0表示当前点可以选择门a,1表示当前点可以选择门b。

算法的时间复杂度为$O(nm)$,空间复杂度为$O(nm)$。

完整代码请查看:solution.py

总结

本题主要考察了图论和动态规划两个知识点,处理技巧较为独特,需要仔细地读题理解,还需要注意算法的时间复杂度和空间复杂度。