蓝桥 1111 第 3 场算法双周赛 迷宫逃脱【算法赛】python解析

迷宫逃脱【算法赛】

时间:2023.11.11
题目地址:迷宫逃脱【算法赛】

题目分析

一拿到手就想着用dfs来看一下,果然不出意外只过了40%,超时了。
那就只能记忆化或者动态规划了。但是动态规划缺只过了35%,然后说错了。不知道是数据的问题,还是代码错了。
搞不懂呢,听说官方的python代码好像也过不了,不知道为啥。

代码

① dfs超时代码,过了40%

def gcd(a, b):
  if a==1 or b==1:
    return True
  while b:
    a, b = b, a % b
  return a == 1

n, m, q = map(int, input().split())
li = []
for _ in range(n):
  li.append(list(map(int, input().split())))

def dfs(x, y, lim, state, summ):
  if x == n-1 and y == m-1:
    summ[0] = max(summ[0], state)
    return
  if x+1 < n:
    if gcd(li[x][y], li[x+1][y]):
      if lim + 1 <= q:
        dfs(x+1, y, lim+1, state+li[x+1][y], summ)
    else:
      dfs(x+1, y, lim, state+li[x+1][y], summ)
  if y+1 < m:
    if gcd(li[x][y], li[x][y+1]):
      if lim + 1 <= q:
        dfs(x, y+1, lim+1, state+li[x][y+1], summ)
    else:
      dfs(x, y+1, lim, state+li[x][y+1], summ)

summ = [-1]
dfs(0, 0, 0, li[0][0], summ)
print(summ[0])

② 动态规划,过了35%

def gcd(a, b):
  if a==1 or b==1:
    return True
  while b:
    a, b = b, a % b
  return a == 1

n, m, q = map(int, input().split())
li = []
for _ in range(n):
  li.append(list(map(int, input().split())))
# 初始化
dp = [[[0 for _ in range(4)] for _ in range(m)] for _ in range(n)]
dp[0][0][0] = li[0][0]
# 行初始化
for i in range(1, m):
  if gcd(li[0][i-1], li[0][i]):
    for k in range(1, q+1):
      if dp[0][i-1][k-1] != 0:
        dp[0][i][k] = dp[0][i-1][k-1] + li[0][i]
  else:
    for k in range(q+1):
      if dp[0][i-1][k] != 0:
        dp[0][i][k] = dp[0][i-1][k] + li[0][i]
# 列初始化
for i in range(1, n):
  if gcd(li[i-1][0], li[i][0]):
    for k in range(1, q+1):
      if dp[i-1][0][k-1] != 0:
        dp[i][0][k] = dp[i-1][0][k-1] + li[i][0]
  else:
    for k in range(q+1):
      if dp[i-1][0][k-1] != 0:
        dp[i][0][k] = dp[i-1][0][k] + li[i][0]

for i in range(1, n):
  for j in range(1, m):
    # 向上
    if gcd(li[i-1][j], li[i][j]):
      for k in range(1, q+1):
        if dp[i-1][j][k-1] != 0:
          dp[i][j][k] = max(dp[i-1][j][k-1] + li[i][j], dp[i][j][k])
    else:
      for k in range(q+1):
        if dp[i-1][j][k] != 0:
          dp[i][j][k] = max(dp[i-1][j][k] + li[i][j], dp[i][j][k])
    # 向左
    if gcd(li[i][j-1], li[i][j]):
      for k in range(1, q+1):
        if dp[i][j-1][k-1] != 0:
          dp[i][j][k] = max(dp[i][j-1][k-1] + li[i][j], dp[i][j][k])
    else:
      for k in range(q+1):
        if dp[i][j-1][k] != 0:
          dp[i][j][k] = max(dp[i][j-1][k] + li[i][j], dp[i][j][k])

ans = max(dp[n-1][m-1])
if ans != 0:
  print(ans)
else:
  print(-1)

小结

有没有好心人指点指点哇 ≡(▔﹏▔)≡

你可能感兴趣的:(#,算法学习的小记录,算法,python)