↓快轉到主要內容
  1. LeetCode/

LeetCode 3651: Minimum Cost Path with Teleportations

·2 分鐘· ·
LeetCode Hard Dynamic-Programming Grid-Dp Matrix Array
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: hard 第一次嘗試:2026-06-26

  • 提交紀錄:Accepted ×3

解題思路
#

dp_t[r][c] = 最多傳送 t 次、走到 (r, c) 的最小成本。

  • t = 0:一般的右 / 下 Grid DP。
  • 從第 t - 1 層到第 t 層:
    1. 傳送:可以從任何值 >= grid[r][c] 的格子傳過來,成本 0。所以「傳送到 (r, c) 的起始成本」= 上一層所有值 >= grid[r][c] 的格子的最小 dp。把格子依值由大到小排序,掃過去維護前綴最小值。
    2. 傳送之後還可以往右 / 下走,再跑一次 Grid DP。

每一層的終點都更新答案,最多 k 層。

我的解法
#

class Solution:
    def minCost(self, grid: List[List[int]], k: int) -> int:
        m, n = len(grid), len(grid[0])
        INF = float("inf")
        cells = sorted(((grid[r][c], r, c) for r in range(m) for c in range(n)), reverse=True)

        def walk(dp: List[List[float]]) -> None:     # 一般的右 / 下 DP
            for r in range(m):
                for c in range(n):
                    if r > 0:
                        dp[r][c] = min(dp[r][c], dp[r - 1][c] + grid[r][c])
                    if c > 0:
                        dp[r][c] = min(dp[r][c], dp[r][c - 1] + grid[r][c])

        dp = [[INF] * n for _ in range(m)]
        dp[0][0] = 0
        walk(dp)
        ans = dp[m - 1][n - 1]

        for _ in range(k):
            best_from = {}                           # 值 -> 上一層「值 >= 它」的最小成本
            running = INF
            for val, r, c in cells:                  # 由大到小
                running = min(running, dp[r][c])
                best_from[val] = running
            dp = [[best_from[grid[r][c]] for c in range(n)] for r in range(m)]
            walk(dp)
            ans = min(ans, dp[m - 1][n - 1])
        return ans

同樣的值會連續出現,best_from[val] 會被覆蓋成「包含所有同值格子」的最小值,所以同值的格子之間也能互相傳送。

複雜度
#

時間 O(mn log(mn) + k · mn),空間 O(mn)。

要特別避免的錯誤
#

  • 傳送的方向:從值大的傳到值小的,所以到 (r, c) 要看值 >= 它的格子。
  • 傳送完要再跑一次一般的 DP,傳送後可以繼續走。

面試口說整理
#

我一層一層算傳送次數。每一層先處理傳送:到某格的成本是上一層所有值不小於它的格子的最小成本,把格子依值由大到小排序、維護前綴最小值就能一次算完;再跑一次右 / 下的 Grid DP。每一層都更新終點的答案。時間 O(mn log(mn) + k · mn)。

相關文章

LeetCode 312: Burst Balloons
·1 分鐘
LeetCode Hard Dynamic-Programming Interval-Dp Array
LeetCode 312 解題筆記:枚舉區間 (i, j) 裡「最後一個」戳破的氣球 k,這時它的鄰居就是 i 和 j,左右兩邊的子問題互相獨立
LeetCode 1537: Get the Maximum Score
·2 分鐘
LeetCode Hard Dynamic-Programming Two-Pointers Greedy Array
LeetCode 1537 解題筆記:兩個排序陣列只在共同的值可以換路;雙指針合併,兩條路各自累加,遇到共同的值時兩邊都取較大的那個再加上它
LeetCode 1458: Max Dot Product of Two Subsequences
·1 分鐘
LeetCode Hard Dynamic-Programming Longest-Common-Subsequence Array
LeetCode 1458 解題筆記:兩個前綴的 DP;dp[i][j] 可以配對 nums1[i]、nums2[j](接在 dp[i-1][j-1] 後面或自己開頭),或跳過其中一個
LeetCode 42: Trapping Rain Water
·1 分鐘
LeetCode Hard Array Two-Pointers Dynamic-Programming Stack
LeetCode 42 解題筆記:每格能存的水是 min(左邊最高, 右邊最高) - 自己的高度;用前後綴最大值或左右雙指針
LeetCode 84: Largest Rectangle in Histogram
·1 分鐘
LeetCode Daily Hard Array Stack Monotonic-Stack Dynamic-Programming Geometry Histogram
使用單調堆疊解決直方圖中最大矩形面積問題
LeetCode 3660: Jump Game IX
·1 分鐘
LeetCode Medium Dynamic-Programming Array
LeetCode 3660 解題筆記:在 i 和 i+1 之間切一刀,如果左邊的最大值 > 右邊的最小值,兩邊就能互相跳到,答案一樣;否則左邊的答案就是左邊的最大值