# Dynamic Programming# Greedy# Array

d378 - 最小路徑

🔗 前往 ZeroJudge 原題

題目描述

題目要求找出一個矩陣中,從左上角到右下角的最短路徑,路徑只能向右或向下移動,路徑的成本是沿途經過的單元格值的總和。

解題思路

本題可以使用動態規劃 (Dynamic Programming) 解決。定義 dp[i][j] 為從左上角 (0, 0)(i, j) 的最小路徑成本。 初始化 dp[0][0]a[0][0]。 對於第一行,dp[0][j] = dp[0][j-1] + a[0][j]。 對於第一列,dp[i][0] = dp[i-1][0] + a[i][0]。 對於其他單元格,dp[i][j] = min(dp[i-1][j] + a[i][j], dp[i][j-1] + a[i][j])。 最後,dp[y-1][x-1] 就是從左上角到右下角的最短路徑成本。

複雜度分析

  • 時間複雜度: O(N*M),其中 N 是矩陣的行數,M 是矩陣的列數。因為需要遍歷整個矩陣一次來計算 dp 值。
  • 空間複雜度: O(NM),因為需要一個大小為 NM 的 dp 矩陣來存儲中間結果。

程式碼

#include <iostream>
using namespace std;
int main(){
	cin.tie(0); ios::sync_with_stdio(false);
	int x,y,ca=0;
	while(cin >> y >> x){
		int a[y][x],dp[y][x];
		for(int i=0;i<y;++i)
			for(int j=0;j<x;++j){
				cin >> a[i][j];
				dp[i][j]=0;
			}
		dp[0][0]=a[0][0];
		for(int i=1;i<y;++i)
			dp[i][0]=a[i][0]+dp[i-1][0];
		for(int j=1;j<x;++j)
			dp[0][j]=a[0][j]+dp[0][j-1];
		for(int i=1;i<y;++i)
			for(int j=1;j<x;++j)
				dp[i][j]=min(a[i][j]+dp[i-1][j],a[i][j]+dp[i][j-1]);
		cout << "Case #" << ++ca << " :\n" << dp[y-1][x-1] << "\n";
	}
}

Discussion