###### tags: `APCS` # **d378-最小路徑** ### **題目連結:** [**d378**](https://zerojudge.tw/ShowProblem?problemid=d378) ### **題目解析** 老鼠在地圖的左上角 (0, 0),只能向右或向下移動,最終要到達右下角 (N-1, M-1)。每走一格都會消耗體力值,消耗的體力值等於該格的數字。題目要求我們找到從起點到終點的所有可能路徑中,體力消耗最少的那條路徑,並輸出其總體力消耗值。 ### **解題方向** 這個問題的解題關鍵在於使用動態規劃: 1. 狀態定義: * 定義一個二維陣列 `route`,其中 `route[i][j]` 表示從左上角 `(0, 0)` 到達該格 `(i, j)` 的最小體力消耗值。 1. 狀態轉移: * 如果老鼠來自左邊的格子 `(i, j-1)`,則 `route[i][j] = route[i][j-1] + grid[i][j]`。 * 如果老鼠來自上面的格子 `(i-1, j)`,則 `route[i][j] = route[i-1][j] + grid[i][j]`。 * `route[i][j] = min(route[i-1][j], route[i][j-1]) + grid[i][j]`,這表示老鼠應該選擇從體力消耗較小的那條路徑來到 `(i, j)`。 1. 初始化: * 對於第一行的每一個格子,只能從左邊的格子移動過來,因此 `route[0][j] = route[0][j-1] + grid[0][j]`。 * 對於第一列的每一個格子,只能從上面的格子移動過來,因此 `route[i][0] = route[i-1][0] + grid[i][0]`。 1. 結果輸出: * 最終結果是 `route[N-1][M-1]`,即從 `(0, 0)` 到達 `(N-1, M-1)` 的最小體力消耗值。 ### **完整程式碼** ```python= case = 1 while True: try: # 讀取 N 和 M N, M = map(int, input().split()) # 讀取地圖->grid,是原始地圖 grid = [] for i in range(N): row = list(map(int, input().split())) grid.append(row) # 初始化 route ,是一個「累計」的陣列 route = [[0 for j in range(M)] for i in range(N)] # 初始化第一行和第一列的邊界條件 route[0][0] = grid[0][0] # 起點 # 對於第一列的每一個格子,只能從上面的格子移動過來 for i in range(1, N): route[i][0] = route[i-1][0] + grid[i][0] # 對於第一行的每一個格子,只能從左邊的格子移動過來 for j in range(1, M): route[0][j] = route[0][j-1] + grid[0][j] # 動態規劃計算最小體力消耗 for i in range(1, N): for j in range(1, M): route[i][j] = min(route[i-1][j], route[i][j-1]) + grid[i][j] # 輸出結果 print("Case #%d :\n%d" % (case, route[N-1][M-1])) case += 1 except: break ```