動態規劃 最大子矩陣(窮舉法 記憶化 DP)

2021-09-22 10:06:46 字數 2408 閱讀 7600

動態規劃:最大子矩陣

在dp問題中有一種叫最大子矩陣問題,剛好碰到了這一題,於是學習分享之。

讓我們先來看一下題目:

題目分類:動態規劃

題目大意:就是輸入乙個n*n的矩陣,找出在矩陣中,所有元素加起來之和最大的子矩陣。

例如在 0 -2 -7 0 這樣乙個4*4的矩陣中,元素之和最大的子矩陣為 9 2  ,它們之和為15。

9 2 -6 2                         -4 1

-4 1 -4 1                         -1 8

-1 8 0 -2

這是乙個最大子矩陣問題,我們怎麼來解決這個問題呢?任何問題都會有它的簡化的問題,這是二維的陣列,與之對應的,我們可以先嘗試一下一維陣列。

如果有乙個一維陣列a[n],如何找出連續的一段,使其元素之和最大呢?

例如有 1 2 -3 4 -2 5 -3 -1 7 4 -6 這樣乙個陣列,那麼顯然 4 -2 5 -3 -1 7 4 這個子陣列元素之和最大,為4+(-2)+5+(-3)+(-3)+7+4=14。為找到一維陣列的最大子陣列,我們可以有以下方法。

1、窮舉法

for(i=0;imax)    max = sum;

}}

窮舉法在n很大的情況下,需要執行的次數非常的多,有三層迴圈,所以n很大時不能使用這種方法。

2、帶記憶的遞推法

record[0] = 0;

for(i=1;i<=n;i++) //用下標1~n來儲存n個數

record[i] = record[i-1] + a[i]; //用record記錄a[i]前i個的和

max = 0;

for(i=1;i<=n;i++)

}

這種方法的時間複雜度明顯比上一種的低了很多,時間複雜度為o(n²)。這種方法其實我們再繼續優化一下,就變成了我們所需要的動態規劃。

3、動態規劃

我們來分析一下最優子結構,若想找到n個數的最大子段和,那麼要找到n-1個數的最大子段和,這就出來了。我們用b[i]來表示a[0]…a[i]的最大子段和,b[i]無非有兩種情況

:(1)最大子段一直連續到a[i]  (2)以a[i]為首的新的子段 。由此我們可以得到b[i]的狀態轉移方程:b[i]=max。最終我們得到的最大子段和為max

return sum;

}4、分治做法

對於任意l,r之間的最大和,取中點m,最大子段和有兩種情況:

1)不包含中點m

2)包含中點m

對於情況1),可以分治為l,m 和m+1 ,r 兩部分,

對於情況2),可以從中點m分別往左,右掃瞄,分別求出兩段的最大子段和,然後相加

最後,情況1)、2)的最大值即為結果。

時間複雜度為nlogn

int fun(int l, int r)

sum = 0;

for(int j = m + 1; j <= r; j++)

return max(t, suml + sumr);

}說了這麼多,這跟最大子矩陣有什麼關係呢?當然有關係學啦!二維就是一維的擴充套件,把二維壓扁不就變成一維了嗎?

我們假設所求n*n的矩陣的最大子矩陣是從i列到j列,q行到p行,如下圖所示(假設下標從1開始)

a[1][1]  a[1][2]  ······  a[1][i]  ······  a[1][j]   ······  a[1][n]

a[2][1]  a[2][2]  ······  a[2][i]  ······  a[2][j]   ······  a[2][n]

a[q][1]  a[q][2]  ······a[q][i]  ······  a[q][j]······  a[q][n]

a[p][1]  a[p][2]  ······a[p][i]  ······  a[p][j]······  a[p][n]

a[n][1]  a[n][2]  ······  a[n][i]  ······  a[n][j]  ······  a[n][n]

最大子矩陣就是圖示加粗部分,如果把最大子矩陣同列的加起來,我們可以得到乙個一維陣列 ,現在我們可以看出,這其實就是乙個一維陣列的最大子段問題。如果把二維陣列看成是縱向的一維陣列和橫向的一維陣列,那問題不就迎刃而解了嗎?把二維轉換成了我們剛剛解決了的問題。

最終我們得到了問題的解法,**如下:

#include #include using namespace std;

int maxsub(int a,int n)

return max;

}int main()

}cout<}

最大子矩陣(動態規劃)

最大矩陣和顧名思義,就是乙個矩陣和最大,例如下面的矩陣 0 2 7 0 9 2 6 2 41 41 1 80 2 最終找到了和為15的矩陣 9 2 41 18所選的矩陣沒有規定,只要在這個大矩陣中,就可以了,那麼我們需要限定它的行和列 我們用三個for迴圈把所有的行的情況列舉,分別是i,j,k i從...

最大子矩陣(動態規劃)解析

已知矩陣的大小定義為矩陣中所有元素的和。給定乙個矩陣,你的任務是找到最大的非空 大小至少是1 1 子矩陣。比如,如下4 4的矩陣 0 2 7 0 9 2 6 2 4 1 4 1 1 8 0 2 的最大子矩陣是 9 2 4 1 1 8 這個子矩陣的大小是15。輸入是乙個n n的矩陣。輸入的第一行給出n...

動態規劃 最大子矩陣的和

問題 最大子矩陣的和 最大子矩陣的和這個問題實際上是子串的最大和向二維空間的擴充套件!我們如果把每一列都看作乙個數的話,實際上也是個子串的最大和問題!不多說啦,大家看 體會吧!package com.liheng.algorithm author administrator 利用動態規劃求最大子矩陣...