You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ZCO 2009 P1:带特殊移动的网格最大权重路径问题求解咨询

嘿,这个问题确实挺棘手的——允许一次反向移动的话,贪心算法肯定抓不住全局最优,毕竟反向移动的收益得结合前后的路径总和来看,不能只看眼前的局部利益。我来分享几种可行的思路,以及这类带特殊规则的路径问题的通用解法:

核心解法:双向动态规划 + 枚举折返点

这个思路的核心是先预处理出两个关键的DP数组,再枚举所有可能使用特殊移动的位置,计算每种情况的最大路径和,最后取所有情况的最大值。

步骤1:预处理正向和反向DP数组

首先我们需要两个DP数组,分别记录从起点到每个点的最优路径,以及从每个点到终点的最优路径:

正向DP数组 forward

forward[i][j] 表示从左上角 (0,0) 走到 (i,j) 的最大路径和。

  • 边界条件:
    • 起点:forward[0][0] = grid[0][0]
    • 第一行(只能从左往右走):forward[0][j] = forward[0][j-1] + grid[0][j]
    • 第一列(只能从上往下走):forward[i][0] = forward[i-1][0] + grid[i][0]
  • 递推公式:对于非边界的点,取从上方或左方过来的最优路径:
    forward[i][j] = grid[i][j] + max(forward[i-1][j], forward[i][j-1])
    

反向DP数组 backward

backward[i][j] 表示从 (i,j) 走到右下角 (n-1,n-1) 的最大路径和。

  • 边界条件:
    • 终点:backward[n-1][n-1] = grid[n-1][n-1]
    • 最后一行(只能从右往左走):backward[n-1][j] = backward[n-1][j+1] + grid[n-1][j]
    • 最后一列(只能从下往上走):backward[i][n-1] = backward[i+1][n-1] + grid[i][n-1]
  • 递推公式:对于非边界的点,取从下方或右方过去的最优路径:
    backward[i][j] = grid[i][j] + max(backward[i+1][j], backward[i][j+1])
    

步骤2:枚举所有可能的特殊移动场景

现在我们要遍历所有可能使用一次反向移动的情况,计算每种情况的路径和,再和“不使用特殊移动”的结果(也就是 forward[n-1][n-1])比较,取最大值:

场景1:使用一次向左移动

遍历所有 i(0 ≤ i < n)和 j(0 ≤ j < n-1),计算路径:起点→(i,j)→(i,j+1)→(i,j)→终点的总和,公式为:

forward[i][j] + grid[i][j+1] + backward[i][j]

这里的逻辑是:forward[i][j] 是到 (i,j) 的最优和,加上走到 (i,j+1) 的数值,再加上从 (i,j) 到终点的最优和(因为我们折返回到了 (i,j))。

场景2:使用一次向上移动

遍历所有 i(0 ≤ i < n-1)和 j(0 ≤ j < n),计算路径:起点→(i,j)→(i+1,j)→(i,j)→终点的总和,公式为:

forward[i][j] + grid[i+1][j] + backward[i][j]

逻辑和向左移动类似,只是折返方向变成了上下。

步骤3:取所有情况的最大值

最终答案就是以下几个值中的最大值:

  • 不使用特殊移动的路径和:forward[n-1][n-1]
  • 所有向左移动场景的最大路径和
  • 所有向上移动场景的最大路径和
为什么这个方法可行?

贪心算法失效的原因是,反向移动的收益不是孤立的——你折返拿到的数值,得加上后续路径的最优解才是真正的收益。而双向DP正好把“起点到每个点的最优”和“每个点到终点的最优”都提前算好了,枚举所有可能的折返点,就能覆盖所有使用特殊移动的路径情况。

这种思路还能扩展到类似问题,比如允许k次特殊移动、特殊移动有不同规则等,核心都是预处理双向最优路径,再枚举特殊操作的位置。

举个实际例子验证

比如下面这个网格:

-5  10
20  -1

常规路径的最大和是 -5→20→-1,总和是14。但如果我们使用一次向左移动:走到 (0,1)(数值10),再折返回到 (0,0),然后走 (0,0)→(1,0)→(1,1),总和是 -5+10+(-5)+20+(-1)=19,比常规路径更优。

用我们的方法计算:

  • forward[0][0] = -5
  • grid[0][1] =10
  • backward[0][0] = max(-5+20+(-1), -5+10+(-1))=14
  • 计算得 -5+10+14=19,正好是最优结果。
复杂度分析
  • 时间复杂度:O(n²),正向DP、反向DP以及枚举场景都是O(n²)的操作,整体是线性的平方级复杂度,对于正方形网格来说效率很高。
  • 空间复杂度:O(n²),用来存储两个DP数组。如果想要优化空间,可以用一维数组代替二维数组,不过n²的空间通常是可接受的。

还要注意:如果折返的点是负数,那使用特殊移动可能反而不如不使用,所以最后一定要和常规路径的结果比较取最大值,不能漏掉这种情况。

内容的提问来源于stack exchange,提问作者Vasu090

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:05:23