leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

commit 94e31f04c637a106ab7a12a58de8a7394f1c631d
parent 1d2c19f97d65f87b641e11127c0853f6e3fb5b7c
Author: Jack Sangdahl <jack@pngu.org>
Date:   Tue, 27 Jan 2026 20:41:11 -0700

3651. minimum cost path with teleportation

Diffstat:
Amin_cost_path_teleportation.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amin_cost_path_teleportation.py | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 151 insertions(+), 0 deletions(-)

diff --git a/min_cost_path_teleportation.c b/min_cost_path_teleportation.c @@ -0,0 +1,94 @@ +// 3651. Minimum Cost Path with Teleportations +#include "leetcode.h" + +/* + * you are given an 'm x n' 2d integer array 'grid' and an integer 'k'. you + * start at the top-left cell '(0, 0)' and your goal is to reach the + * bottom-right cell '(m - 1, n - 1)'. there are two types of moves available: + * normal move you can move righ or down from your current cell '(i, j)' ie. you + * can move to '(i, j + 1)' (right) or '(i + 1, j)' (down). the cost is the + * value of the destination cell. teleportation you can teleport from any cell + * '(i, j)' to any cell '(x, y)' such that 'grid[x][y] <= grid[i][j]'; the cost + * of this move is 0. you may teleport at most 'k' times. return the minimum + * total cost to reach cell (m - 1, n - 1) from '(0, 0)'. + */ + +int minCost(int **grid, int gridSize, int *gridColSize, int k) { + int m = gridSize, n = gridColSize[0]; + int total = (k + 1) * m * n; + int *dp = (int *)malloc(total * sizeof(int)); + int *min_cost = (int *)malloc(10002 * sizeof(int)); + for (int i = 0; i < total; i++) + dp[i] = INT_MAX; + dp[0] = 0; + for (int t = 0; t <= k; t++) { + int offset = t * m * n; + for (int r = 0; r < m; r++) { + for (int c = 0; c < n; c++) { + int curr = offset + r * n + c; + if (dp[curr] == INT_MAX) + continue; + int cost = dp[curr]; + if (r + 1 < m) { + int down = offset + (r + 1) * n + c; + long long next = (long long)cost + grid[r + 1][c]; + dp[down] = fmin(dp[down], next); + } + if (c + 1 < n) { + int right = offset + r * n + (c + 1); + long long next = (long long)cost + grid[r][c + 1]; + dp[right] = fmin(dp[right], next); + } + } + } + if (t < k) { + for (int i = 0; i < 10002; i++) + min_cost[i] = INT_MAX; + for (int r = 0; r < m; r++) { + for (int c = 0; c < n; c++) { + int idx = offset + r * n + c; + if (dp[idx] != INT_MAX) { + int val = grid[r][c]; + min_cost[val] = fmin(min_cost[val], dp[idx]); + } + } + } + int curr_min = INT_MAX; + for (int v = 10000; v >= 0; v--) { + if (min_cost[v] < curr_min) + curr_min = min_cost[v]; + else + min_cost[v] = curr_min; + } + int next = (t + 1) * m * n; + for (int r = 0; r < m; r++) { + for (int c = 0; c < n; c++) { + int val = grid[r][c]; + int idx = next + r * n + c; + dp[idx] = fmin(dp[idx], min_cost[val]); + } + } + } + } + int ans = INT_MAX, idx = (m - 1) * n + (n - 1); + for (int t = 0; t <= k; t++) { + int i = t * m * n + idx; + ans = fmin(ans, dp[idx]); + } + free(dp); + free(min_cost); + return ans; +} + +int main() { + int g1i[3][3] = {{1, 3, 3}, {2, 5, 4}, {4, 3, 5}}; + int g2i[3][2] = {{1, 2}, {2, 3}, {3, 4}}; + struct two_d_arr *g1 = + two_d_arr_init(ARRAY_SIZE(g1i), ARRAY_SIZE(g1i[0]), g1i); + struct two_d_arr *g2 = + two_d_arr_init(ARRAY_SIZE(g2i), ARRAY_SIZE(g2i[0]), g2i); + printf("%d\n", minCost(g1->arr, g1->row_size, g1->col_size, 2)); // expect: 7 + printf("%d\n", minCost(g2->arr, g2->row_size, g2->col_size, 1)); // expect: 9 + two_d_arr_free(g1); + two_d_arr_free(g2); +} diff --git a/min_cost_path_teleportation.py b/min_cost_path_teleportation.py @@ -0,0 +1,57 @@ +# 3651. Minimum Cost Path with Teleportations +from itertools import accumulate + +""" +you are given an 'm x n' 2d integer array 'grid' and an integer 'k'. you +start at the top-left cell '(0, 0)' and your goal is to reach the +bottom-right cell '(m - 1, n - 1)'. there are two types of moves available: +normal move you can move righ or down from your current cell '(i, j)' ie. you +can move to '(i, j + 1)' (right) or '(i + 1, j)' (down). the cost is the +value of the destination cell. teleportation you can teleport from any cell +'(i, j)' to any cell '(x, y)' such that 'grid[x][y] <= grid[i][j]'; the cost +of ttotals move is 0. you may teleport at most 'k' times. return the minimum +total cost to reach cell (m - 1, n - 1) from '(0, 0)'. +""" + + +class Solution(object): + def minCost(self, grid, k): + """ + :type grid: List[List[int]] + :type k: int + :rtype: int + """ + m, n = len(grid), len(grid[0]) + total = max([max(row) for row in grid]) + dp = None + costs = [[0] * n for _ in range(m)] + for x in range(k + 1): + for i in range(m - 1, -1, -1): + for j in range(n - 1, -1, -1): + costs[i][j] = float("inf") + if i == m - 1 and j == n - 1: + costs[i][j] = 0 + else: + if i < m - 1: + s = costs[i + 1][j] + grid[i + 1][j] + if s < costs[i][j]: + costs[i][j] = s + if j < n - 1: + s = costs[i][j + 1] + grid[i][j + 1] + if s < costs[i][j]: + costs[i][j] = s + if x > 0 and dp[grid[i][j]] < costs[i][j]: + costs[i][j] = dp[grid[i][j]] + dp = [float("inf")] * (total + 1) + for i in range(m): + for j in range(n): + if costs[i][j] < dp[grid[i][j]]: + dp[grid[i][j]] = costs[i][j] + dp = list(accumulate(dp, min)) + return costs[0][0] + + +if __name__ == "__main__": + obj = Solution() + print(obj.minCost(grid=[[1, 3, 3], [2, 5, 4], [4, 3, 5]], k=2)) + print(obj.minCost(grid=[[1, 2], [2, 3], [3, 4]], k=1))