/** * File: min_path_sum.kt * Created Time: 2024-01-25 * Author: curtishd (1023632660@qq.com) */ package chapter_dynamic_programming import java.util.* import kotlin.math.min /* 最小路徑和:暴力搜尋 */ fun minPathSumDFS( grid: Array>, i: Int, j: Int ): Int { // 若為左上角單元格,則終止搜尋 if (i == 0 && j == 0) { return grid[0][0] } // 若行列索引越界,則返回 +∞ 代價 if (i < 0 || j < 0) { return Int.MAX_VALUE } // 計算從左上角到 (i-1, j) 和 (i, j-1) 的最小路徑代價 val up = minPathSumDFS(grid, i - 1, j) val left = minPathSumDFS(grid, i, j - 1) // 返回從左上角到 (i, j) 的最小路徑代價 return (min(left.toDouble(), up.toDouble()) + grid[i][j]).toInt() } /* 最小路徑和:記憶化搜尋 */ fun minPathSumDFSMem( grid: Array>, mem: Array>, i: Int, j: Int ): Int { // 若為左上角單元格,則終止搜尋 if (i == 0 && j == 0) { return grid[0][0] } // 若行列索引越界,則返回 +∞ 代價 if (i < 0 || j < 0) { return Int.MAX_VALUE } // 若已有記錄,則直接返回 if (mem[i][j] != -1) { return mem[i][j] } // 左邊和上邊單元格的最小路徑代價 val up = minPathSumDFSMem(grid, mem, i - 1, j) val left = minPathSumDFSMem(grid, mem, i, j - 1) // 記錄並返回左上角到 (i, j) 的最小路徑代價 mem[i][j] = (min(left.toDouble(), up.toDouble()) + grid[i][j]).toInt() return mem[i][j] } /* 最小路徑和:動態規劃 */ fun minPathSumDP(grid: Array>): Int { val n = grid.size val m = grid[0].size // 初始化 dp 表 val dp = Array(n) { IntArray(m) } dp[0][0] = grid[0][0] // 狀態轉移:首行 for (j in 1..>): Int { val n = grid.size val m = grid[0].size // 初始化 dp 表 val dp = IntArray(m) // 狀態轉移:首行 dp[0] = grid[0][0] for (j in 1..