1 条题解
-
0
一、题目核心理解
迷宫是分层结构:
- 第 层 = 所有满足 的格子。
- 第 层:
- 第 层:
- 第 层:,以此类推。
层与层之间只有两个门:
- 顶部墙的门:在第 层的顶部边上,即 且 。
- 右侧墙的门:在第 层的右侧边上,即 且 。
二、关键观察
-
同一层内移动:
层内格子形成一个“L”形或矩形,但实际可走路径是曼哈顿距离,因为同一层内没有墙(墙只在层之间)。 -
跨层移动:
只能通过两个门进入下一层(或上一层)。
进入下一层后,必须立刻在该层内走到该层的另一个门才能继续往下。 -
最优路径结构:
从第 层到第 层():- 先在 层内走到该层的某个门
- 进入 层
- 在 层内走到该层的某个门
- 继续直到 层
- 最后在 层内走到目标点
三、动态规划预处理
定义 = 第 层顶部墙上的门坐标, = 第 层右侧墙上的门坐标(坐标从 开始)。
1. 层间转移代价
从第 层到第 层:
-
如果从 层的顶部门 出发,进入 层后,要走到 层的某个门 ():
- 进入 层的点: 正上方一格?不对,门在 层顶部,进入 层后位置是 。
- 因为 ,门在 和 之间。
- 进入 层后位于 。
- 然后走到 的距离:
- 若 (顶部门): → ,曼哈顿距离 = ,然后要进入下一层?不对,这里是走到 层的门,还没跨层。
- 实际上代码中是:
因为 (0-based),加 1 后为 ,所以 是层内距离, 是穿过门的那一步。abs(d[i][0].x + 1 - d[i+1][k].x) + abs(d[i][0].y - d[i+1][k].y) + 1
-
如果从 层的右侧门 出发,进入 层后位于 :
abs(d[i][1].x - d[i+1][k].x) + abs(d[i][1].y + 1 - d[i+1][k].y) + 1
所以定义:
- = 从第 层顶部门到第 层第 个门的最小步数。
- = 从第 层右侧门到第 层第 个门的最小步数。
但代码中 的 是从 到 ,表示从第 i+1 层到第 i+2 层?要仔细看。
其实索引:
- 有 层门的信息(第 1 到 n-1 层的门)。
- 层间转移:从第 层( 从 1 到 n-2)到第 层,需要 和 。
所以 表示从第 层的门 到第 层的门 的最小代价?不对,看下标:
代码中:
forn(i, n-2) forn(k,2){ dp[i][0][0][k] = abs(d[i][0].x+1 - d[i+1][k].x) + abs(d[i][0].y - d[i+1][k].y) + 1; dp[i][0][1][k] = abs(d[i][1].x - d[i+1][k].x) + abs(d[i][1].y+1 - d[i+1][k].y) + 1; }这里 和 的索引: 从 0 到 n-3, 和 都存在(因为 长度 )。
所以 表示:从第 层的门 到第 层的门 的最小步数。
四、倍增优化
用倍增(binary lifting)合并区间:
dp[i][l][j][k] = min over t ( dp[i][l-1][j][t] + dp[i + (1<<(l-1))][l-1][t][k] )这样可以在 时间内从第 层跳到第 层。
五、查询处理
对于询问 :
- 计算所在层 ,,若 则交换。
- 若同层:直接曼哈顿距离。
- 否则:
- 从起点走到第 层的两个门的代价:
注意这里 是第 层的门坐标(0-based),起点坐标也是 0-based。ndp[0] = |x1 - d[l1][0].x| + |y1 - d[l1][0].y| ndp[1] = |x1 - d[l1][1].x| + |y1 - d[l1][1].y| - 用倍增从 跳到 (因为最后要进入 层),每次合并 :
tmp[k] = min(ndp[j] + dp[l1][i][j][k]) - 最后从 层的门走到终点:
这里 经过倍增后已经变成 。ans = min( ndp[0] + |d[l1][0].x+1 - x2| + |d[l1][0].y - y2| + 1, ndp[1] + |d[l1][1].x - x2| + |d[l1][1].y+1 - y2| + 1 )
- 从起点走到第 层的两个门的代价:
六、复杂度
- 预处理:
- 每个查询:
总复杂度 ,可以通过 。
七、代码对应关系
- :第 层顶部门的坐标
- :第 层右侧门的坐标
- :从第 层门 到第 层门 的最小步数
- :当前所在层的两个门的累计代价
八、核心公式
层内曼哈顿距离:
$$\text{dist}((x_1,y_1),(x_2,y_2)) = |x_1-x_2| + |y_1-y_2| $$跨层代价(从第 层顶部门到第 层门 ):
$$|(i+1) - d[i+1][k].x| + |d[i][0].y - d[i+1][k].y| + 1 $$跨层代价(从第 层右侧门到第 层门 ):
$$|d[i][1].x - d[i+1][k].x| + |(i+1) - d[i+1][k].y| + 1 $$倍增合并:
$$dp[i][l][j][k] = \min_{t \in \{0,1\}} \left( dp[i][l-1][j][t] + dp[i+2^{l-1}][l-1][t][k] \right) $$查询答案:
$$\min\left( \begin{aligned} &ndp[0] + |d[l_2-1][0].x+1 - x_2| + |d[l_2-1][0].y - y_2| + 1, \\ &ndp[1] + |d[l_2-1][1].x - x_2| + |d[l_2-1][1].y+1 - y_2| + 1 \end{aligned} \right) $$
- 1
信息
- ID
- 6633
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者