算法-交替方向的最小路径代价III-Dijkstra最短路径算法

题目

给你两个整数 m 和 n,表示一个网格的行数和列数。你的目标是到达单元格 (m - 1, n - 1)。同时给你一个二维整数数组 penalty。

进入单元格 (i, j) 的代价为 (i + 1) * (j + 1)。

你从单元格 (0, 0) 开始,最初需要支付其入口代价。进入 (0, 0) 后执行的行动从 1 开始编号。

在每次行动中,你可以移动到一个 相邻的单元格,或者在当前单元格等待。如果满足以下条件,则移动遵循奇偶性规则:

  • 在 奇数编号 的行动中,你向 右 或向 下移动。
  • 在 偶数编号 的行动中,你向 左 或向 上移动。

行动的代价由以下方式决定:

  • 如果你遵循奇偶性规则移动,只需支付目标单元格的入口代价。
  • 如果你在 违反 奇偶性规则的方向上移动,支付目标单元格的入口代价加上 penalty[i][j],其中 (i, j) 是你移动前所在的单元格。
  • 如果你在单元格 (i, j) 中等待 ,支付 penalty[i][j]。

在每次移动或等待之后,行动编号增加 1。因此,无论是否支付了惩罚代价,所需遵循的奇偶性规则在每次行动后都会交替改变。

返回到达 (m - 1, n - 1) 所需的 最小总代价。

示例 1:

输入: m = 2, n = 2, penalty = \[5,3,1,4]

输出: 8

解释:

最优路径为:

  • 从单元格 (0, 0) 开始,入口代价为 (0 + 1) * (0 + 1) = 1。
  • 行动 1 :向下移动到单元格 (1, 0),入口代价为 (1 + 1) * (0 + 1) = 2。
  • 行动 2 :向右移动到单元格 (1, 1),入口代价为 (1 + 1) * (1 + 1) = 4,因为违反了偶数奇偶性规则,额外代价为 penalty[1][0] = 1。

因此,总代价为 1 + 2 + 4 + 1 = 8。

题解

思路:Dijkstra最短路径算法模版题,需要注意的是除了优先级队列,还需要一个最小值数组维护答案,举例:比如从A出发到C,有两条路径,A->C是权值是5,先A->B,全值是3,然后B->C,权值是4,按优先级队列,会先走A->B,再走B->C,权值和是7,但实际上是从A->C权值是5,权值最小,这就需要一个最小值数组,另外需要考虑的就是最小值数组维护的维度。

java 复制代码
class Solution {
    // 奇数下标 1,3 对应向右或向下
    // 偶数下标 0,2 对应向左或向上
    private static final int[][] DIRS = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}}; // 左右上下

    private record Node(long d, int i, int j, int k) {
    }

    public long minCost(int m, int n, int[][] penalty) {
        long[][][] dis = new long[m][n][2];
        for (long[][] mat : dis) {
            for (long[] row : mat) {
                Arrays.fill(row, Long.MAX_VALUE);
            }
        }

        PriorityQueue<Node> pq = new PriorityQueue<>((a, b) -> Long.compare(a.d, b.d));

        // 支付 1 的入口代价
        dis[0][0][1] = 1;
        pq.offer(new Node(1, 0, 0, 1));

        while (true) {
            Node top = pq.poll();
            long d = top.d;
            int i = top.i;
            int j = top.j;
            int k = top.k;
            if (i == m - 1 && j == n - 1) {
                return d;
            }
            if (d > dis[i][j][k]) {
                continue;
            }
            int p = penalty[i][j];

            // 原地不动
            long newDis = d + p;
            if (newDis < dis[i][j][k ^ 1]) {
                dis[i][j][k ^ 1] = newDis;
                pq.offer(new Node(newDis, i, j, k ^ 1)); // k^1 切换行动编号的奇偶性
            }

            // 移动一步
            for (int idx = 0; idx < 4; idx++) {
                int x = i + DIRS[idx][0];
                int y = j + DIRS[idx][1];
                if (0 <= x && x < m && 0 <= y && y < n) {
                    // 如果 k 和 idx 的奇偶性不同,那么违反了奇偶性规则,需要额外支付 p 的代价
                    newDis = d + (x + 1) * (y + 1) + (idx % 2 ^ k) * p;
                    if (newDis < dis[x][y][k ^ 1]) {
                        dis[x][y][k ^ 1] = newDis;
                        pq.offer(new Node(newDis, x, y, k ^ 1)); // k^1 切换行动编号的奇偶性
                    }
                }
            }
        }
    }
}
相关推荐
乐迪信息3 分钟前
港口船舶逆行怎么管?AI防爆摄像机搭载智能检测算法
大数据·人工智能·深度学习·算法·计算机视觉
Sirens.1 小时前
Java并发锁详解:六类锁策略与 synchronized 底层原理
java·前端·算法
和裕1 小时前
全纸结构重型纸箱能否满足 1 吨以上设备出口熏蒸豁免要求?通关合规性全解析
大数据·运维·网络·人工智能·算法
tangguofeng2 小时前
不带头结点的链队操作集(不含InitFlag)(C语言版)
算法
苏打豆3 小时前
CRISP源码阅读——基于ROS2力矩反馈控制器与速度加速度零空间
c++·线性代数·算法·矩阵·机器人
蛋蛋的就会顺顺的4 小时前
hot100——矩阵
java·数据结构·算法·leetcode·力扣
老歌老听老掉牙4 小时前
麻花钻切屑形态演变的力学机制与临界条件分析
python·算法·钻头
zhangfeng11334 小时前
国产GPU/AI算力芯片现状(修订完整版 · 截至2026年9月
人工智能·算法·ai编程·npu
学代码的CJY5 小时前
从代码出发理解时间复杂度与空间复杂度
数据结构·算法
白帽攻防录5 小时前
SRC 挖洞:WSO2 JWT 算法混淆绕过深度复盘,CVE-2026-5430 不支持的算法怎么变成管理员
网络·算法·安全·网络安全·jwt