矩陣的最小路徑和

2021-10-24 07:45:11 字數 2283 閱讀 9030

矩陣的最小路徑和

給定乙個 n * m 的矩陣 a,從左上角開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有的數字累加起來就是路徑和,輸出所有的路徑中最小的路徑和。

輸入描述:

第一行輸入兩個整數 n 和 m,表示矩陣的大小。

接下來 n 行每行 m 個整數表示矩陣。

輸出描述:

輸出乙個整數表示答案。

示例1輸入

4 4

1 3 5 9

8 1 3 4

5 0 6 1

8 8 4 0

輸出
12
備註:

1 ≤n

,m

≤2000

1 \leq n,m \leq 2000

1≤n,m≤

20000≤

aij≤

1000 \leq a_ \leq 100

0≤aij​

≤100

題解:狀態轉移方程:f[i, j] = min(f[i - 1,j], f[i, j - 1]) + a[i, j],下面逐步對它進行優化:

基礎版本解法:

用另外乙個空間大小為 n×m

n \times m

n×m 的陣列進行狀態更新,這樣搭配原陣列,空間大小為:o(2

×n×m

)o(2 \times n \times m)

o(2×n×

m)基礎版本解法**:

#include

#include

using

namespace std;

const

int n =

2010

;int a[n]

[n];

int f[n]

[n];

int n, m;

void

solve()

}printf

("%d\n"

, f[n -1]

[m -1]

);}int

main

(void)if

(!j)}}

solve()

;return0;

}

優化一:

我們可以直接在原陣列 a 上進行更新,不需要開闢新的陣列,這樣能節省一些空間。

優化一**:

#include

#include

using

namespace std;

const

int n =

2010

;int a[n]

[n];

int f[n]

[n];

int n, m;

void

solve()

}printf

("%d\n"

, f[n -1]

[m -1]

);}int

main

(void)if

(!j)

if(i && j)}}

//solve();

printf

("%d\n"

, a[n -1]

[m -1]

);return0;

}

優化二:

觀察狀態轉移方程,f[i, j] 只跟 f[i - 1, j] 和 f[i, j - 1] 有關,於是我們可以使用乙個額外的陣列記錄上一層狀態,即新的狀態轉移方程為:f[i] = min(f[i - 1], f[i]) + a[i,j],其中 a[i, j] 可以在輸入時處理,不用開闢乙個陣列去儲存,這樣的話,空間複雜度為 o(m

)o(m)

o(m)

。優化二**:

#include

#include

using

namespace std;

const

int n =

2010

;const

int inf =

0x3f3f3f3f

;int n, m;

int f[n]

;void

solve()

f[0]

= inf;

int now;

while

(n--

>1)

}printf

("%d\n"

, f[m]);

}int

main

(void

)

矩陣的最小路徑和

準備校招的!這些是一本書的筆記 程式設計師 面試指南 it名企演算法與資料結構題目最優解 左程雲 給定乙個矩陣m,從左上角開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有的數字累加起來就是路徑和,返回所有的路徑中最小的路徑和 舉例 如果給定的m如下 135 9 813 4 506 1 8...

矩陣的最小路徑和

給定乙個矩陣m,從左上角開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有的數字累加起來就是路徑和,返回所有的路徑中最小的路徑和。方法一 遞迴 coding utf 8 defsolution m,l n l m 0 0 if len m 1 and len m 0 1 return l ...

矩陣的最小路徑和

題目 給定乙個矩陣m,從左上角開始每次只能向右或者向下走,最後達到右下角的位置,路徑上所有的數字累加起來就是路徑和,返回所有的路徑中最小的路徑和。舉例 給定的m如下 1 3 5 9 8 1 3 4 5 0 6 1 8 8 4 0 路徑1,3,1,0,6,1,0是所有路徑中路徑和最小的,所以返回12。...