矩陣的最小路徑和
給定乙個 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。...