從本文開始,我打算多刷一些動態規劃的題。不僅如此,各種典型演算法也會在分類刷一刷。
【題目】
給定乙個矩陣,從左上角開始每次只能向右或者右下走,最後到達右下角的位置,路徑上所有數字累加起來就是路徑和,返回所有路徑中最小的路徑和。
【舉例】
如果給定的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。
【解答】
這道題是很明顯的動態規劃演算法,動態規劃演算法的一般步驟就是列一張表來存放計算過的值,通常採用陣列實現。這道題的特殊之處在於表的值不僅和自身有關,而且和原矩陣也是相關的。表中的值需要和原矩陣中的值相加,因為我們求的是路徑和。
矩陣如下,只畫了一部分,動態規劃通常會申請+1的空間,i=0和j=0用來存放動態規劃的初始值,這裡我們賦為0,這張表是b[m+1][n+1]。
:0 1 2 3 4
0: 0 0 0 0 0
1: 0 14
918
2:0 9 5
...不難看出,b[1][j]和b[i][1]是取它上下兩個相鄰值再加上原陣列a[i-1][j-1]的值(看1和4),為什麼減一是因為規劃表真實資料從1開始而不是從0開始。這些其實是為了初始化下標為1的這些點。
除了下標為i=1或j=1的部分,其他值(看5)是上下相鄰兩個值得最小值與原陣列a[i-1][j-1]的值相加。這就是dp陣列的公式了。
我第一種解法就沒有初始化,直接放在迴圈裡面做了,不過效率肯定不高,下面是我第一種解法,可以和第二種對比一下。
for(int i=1; i<=m; ++i)
}
其實最早的第一次解我都沒有考慮到下標為1的應該是max,當時我直接只用了乙個min,然後求得結果為11,還好我認識到了錯誤。
起始也不用std::max,直接相加就行了
下面看第二種完整**,注意第二種只是參考,還有第三種,我沒有刪除這個是為了警示我自己考慮要周全,突然又想到的。
int min_path(const std::vector>& a)
}
return b[m][n];
}
第三種:分配同樣的大小就可以了,不需要i-1和j-1了。
int min_path(const std::vector>& a)
, ,,};
int find = min_path(a);
std::cout<<"the min path is : "<>::iterator iterator1;
typedef std::vector::iterator iterator2;
for(iterator1 iter= a.begin(); iter!=a.end(); ++iter){
for(iterator2 it = (*iter).begin(); it!=(*iter).end(); ++it)
std::cout<<*it<<' ';
std::cout<
DP 矩陣的最小路徑和
給定乙個矩陣m,從左上角開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有的樹子累加起來就是路徑和,返回所有的路徑中最小的路徑和.這是一道經典的動態規劃題,狀態轉移方程為dp i j min m i j 可以用乙個二維的dp矩陣來求解.對於dp矩陣,第一行和第一列只會有一種走法,就是從左到...
DP題解 矩陣最小路徑和問題
dp題解 矩陣最小路徑和問題 題目 給定乙個矩陣,例如demo,從左上角開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有的數字累加起來就是路徑和,返回所有的路徑和中最小的路徑和。演算法分析 這是乙個典型的動態規劃演算法問題。分析如下 例如下圖中的矩陣demo,1 3 1 0 6 1 0 ...
矩陣的最小路徑和
準備校招的!這些是一本書的筆記 程式設計師 面試指南 it名企演算法與資料結構題目最優解 左程雲 給定乙個矩陣m,從左上角開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有的數字累加起來就是路徑和,返回所有的路徑中最小的路徑和 舉例 如果給定的m如下 135 9 813 4 506 1 8...