懸線法(解決最大子矩陣型別的問題)

2021-09-25 15:06:54 字數 1315 閱讀 2852

顧名思義:懸線法就如條懸著的線一般

先定義幾樣東西

【定義子矩形】

有效子矩形:內部不包含障礙點的、輪廓與整個矩形平行或重合的子矩形

極大子矩形:每條邊都不能向外擴充套件的有效子矩形。

最大子矩形:所有有效子矩形中最大的乙個(或多個)。

我們可以很顯然的看出:乙個子矩陣要最大,那麼這個子矩陣一定不能再向上,下,坐,右擴充套件,那麼可得最大子矩陣是屬於極大子矩陣的,那麼我們只需要找出所有極大子矩陣,然後取最大值就求出了最大子矩陣做法:用一條線左右移動直到不滿足約束條件或者到達邊界

再定義幾個東西:

left[i][j]:代表從(i,j)能到達的最左位置

right[i][j]:代表從(i,j)能到達的最右位置

up[i][j]:代表從(i,j)向上擴充套件最長長度.

遞推公式

left[i][j]=max(left[i][j],left[i-1][j]

right[i][j]=min(right[i][j],right[i−1][j]

為什麼left取max,rigth取min,因為要滿足向上能擴充套件的所有層的左右擴充套件的長度這個遞推式看起來像是很偏袒上面的,一直照顧上面的情況,那左右能擴充套件的極大子矩陣怎麼沒表現出來呢?

在這張圖上我們可以看到,高的子矩陣最下面的點都會遞推到它這個極大子矩陣(因為能向上就向上),但是在這個高的極大子矩陣覆蓋之外,也是按照能向上就向上(極大化)思想,也可以找出其他的極大子矩陣.

我們可以這麼來證明:

因為矩陣中的每個點都會被列舉到,那麼如果這個點屬於乙個相對高的極大子矩陣又屬於乙個相對矮的極大子矩陣,那麼這個點的值一定是相對高的極大子矩陣的值,那相對矮的極大子矩陣若不是被所有高的極大子矩陣覆蓋,那麼必有乙個點只屬於這個矮的或比它更矮的極大子矩陣,所以這個矮的極大子矩陣在沒有被其他極大子矩陣完全覆蓋的情況下絕對會被列舉出來.

極大子矩陣 懸線法總結

顧名思義,就是從每乙個點 或者邊界 開始,以此為邊界,開始像用一根豎線一樣不斷移動,在遇到障礙點或邊界時確定出極大子矩陣。核心內容就是確定一條邊界,不斷擴充套件並修改其他邊界 可能有點抽象,做題理解一下就好。在 wzk 大佬的國家隊 用極大化思想解決最大子矩陣問題中有詳細的講解 從題目入手講解 本人...

洛谷P4147 最大子矩陣處理 懸線法

題目大意 第一行n,m表示矩形土地有n行m列。接下來輸入土地,由f和r組成,問最大的f矩形土地的面積,答案乘以3 將f置為1,r置為0,相當於求最大1矩陣的面積 l i j 表示從座標 i,j 最左邊到達0的位置 r i j 表示從座標 i,j 最右邊到達0的位置 h i j 表示從座標 i,j 向...

P4147 玉蟾宮 懸線法求最大子矩陣

p4147 玉蟾宮 懸線法,l r up 分別表示 i,j 這個點向左,右,上能到達的遠點。然後面積就很好辦了。具體實現見 然而,還有更優秀的演算法,可是我還沒學會嚶嚶嚶,可以看看這題 p1578 奶牛浴場 includeusing namespace std const int n 1005 in...