最大的和 最大子矩陣和 貪心 字首和 dp

2021-10-03 03:05:55 字數 1572 閱讀 5476

給定乙個包含整數的二維矩陣,子矩形是位於整個陣列內的任何大小為1 * 1或更大的連續子陣列。

矩形的總和是該矩形中所有元素的總和。

在這個問題中,具有最大和的子矩形被稱為最大子矩形。

例如,下列陣列:

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,表示方形二維陣列的大小。

從第二行開始,輸入由空格和換行符隔開的n2n2個整數,它們即為二維陣列中的n2n2個元素,輸入順序從二維陣列的第一行開始向下逐行輸入,同一行資料從左向右逐個輸入。

陣列中的數字會保持在[-127,127]的範圍內。

輸出格式

輸出乙個整數,代表最大子矩形的總和。

資料範圍

1≤n≤100

輸入樣例:

4

0 -2 -7 0 9 2 -6 2

-4 1 -4 1 -1

8 0 -2

輸出樣例:

15
思路:因為要求矩陣所有數的和,所以可以首先處理出縱向的每一豎列的字首和,將求乙個豎列的和的時間複雜度從o(n)優化成o(1),只需要算出a[j][k]-a[i-1][k],就是以第i行為上界,以第j行為下界,第k列這一豎列的和(雖然只有一條豎線,但也可以看成乙個矩形,乙個矩形就是由這若干條豎線組成的),然後利用貪心的思想,類似dp的處理方法,在矩陣的上下界(i和j確定的矩陣的高)固定的情況下,列舉k從1到n(即矩陣的寬),要求最大矩陣和,每次乙個豎列向右擴充套件時,得到的矩陣的最大和都與上乙個狀態的最大和有關,這就涉及到決策的最優問題(類似dp最大不相交欄位和),就把二維的問題轉化成了一維的問題,這裡只不過是之前在求dp最大不相交欄位和問題中的每乙個數都變成了一條線段的和(這條線段的和使用上面字首和的公式o(1)次的算出的),所以每次決策時,當前最大和=max(上一次的最大和,0)+當前豎列的和(即:上乙個最大和》0就累加上,否則當前豎列的和就是當前最大和)

最後總結一下,就是列舉上下界(高度)(o(n^2)),然後列舉所有寬度(o(n)),用dp+字首和算出當前最大和,這樣時間複雜度就是o(n^3).

完整**:

#include using namespace std;

const int inf=0x3f3f3f3f;

int n,a[110][110];

int main()

}int ans=-inf;

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

cout

}

最大子矩陣 字首和 貪心

給定乙個包含整數的二維矩陣,子矩形是位於整個陣列內的任何大小為1 1或更大的連續子陣列。矩形的總和是該矩形中所有元素的總和。在這個問題中,具有最大和的子矩形被稱為最大子矩形。例如,下列陣列 0 2 7 0 9 2 6 2 4 1 4 1 1 8 0 2 其最大子矩形為 9 2 4 1 1 8 它擁有...

最大子段和 最大子矩陣和

給出n個整數序列 可能為負數 組成的序列a1,a2,an,求該序列形如 的子段和的最大值。當所有整數均為負數時,定義最大子段和為0。多測試用例。每個測試用例佔2行 第一行是序列的個數n 0 n 10000 第二行是n個整數。為每個測試用例輸出一行結果 最大子段和。6 2 11 4 13 5 2 31...

1224 最大子矩陣(字首和)

門2是用的一維字首和,門1的一維字首和 好像有點錯誤。直接cv了 這個 裡,這樣輸入矩陣的方式還是第一次見,字首和是計算的每一列的。include include include include include define inf 999999999 define n 1001 using nam...