題解 新技巧 一本通1282 最大子矩陣

2022-04-12 03:20:39 字數 1431 閱讀 3138

題目傳送)

雖然已知是dp,但第一眼看挺矇的,想了想後設了個a[i][j][k][l]表示長(座標)為i~j,寬(座標)為k~l的矩陣,但根本找不到狀態轉移方程啊。後借鑑題解(後領悟到的另一種方法:

任何問題都有它的簡化,看到二維,沒辦法時我們可以考慮一下一維:求一維陣列的乙個最大連續段,我們可以設b[i]為從前i個數的最大連續段(a[i]為一開始存入的輸入資料),b[i]無非就有兩種情況:以它結尾的最大連續段;或以它開頭另開乙個最大連續段(當b[i-1]小於0時b[i-1]+a[i]反而比a[i]小,因此不如新開乙個最大連續段)。

1

int maxsubarray(int a,intn)2

13return

sum;

14 }

想完一維,跟二維有什麼關係?當然有了,我們把二維「拍」成一維,不就行了嗎?

我們假設所求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]

最大子矩陣就是圖示紅色部分,如果把最大子矩陣同列的加起來,我們可以得到乙個一維陣列 ,現在我們可以看出,這其實就是乙個一維陣列的最大子段問題:

分別將各個高的矩陣壓縮成乙個一維陣列並求它的最大連續段,則在二維的體現就是乙個相應高的最大連續矩陣,取所有相應最大連續矩陣的最大值,就是答案(還好題目只要求最大值,不要求給出最大矩陣是什麼)

ac**:

1 #include2 #include3 #include4

using

namespace

std;

5int dp[101][101],arr[101];6

int maxsub(int a,intn)7

17return

max;18}

19int

main()

2037

}38 cout<39return0;

40 }

最後總結一下:1.對問題的簡化(二維轉一維,模擬轉整體充分條件(長方體),無序轉有序等)十分重要!

2.線型動態規劃多以結尾為狀態。

題解 一本通1224 最大子矩陣

花兩分鐘靜心看看,望您有所收穫 1224 最大子矩陣 時間限制 1000 ms 記憶體限制 65536 kb 提交數 3073 通過數 1958 已知矩陣的大小定義為矩陣中所有元素的和。給定乙個矩陣,你的任務是找到最大的非空 大小至少是1 11 1 子矩陣。比如,如下 4 4 的矩陣 0 2 7 0...

一本通 最大連續和

寫下單調佇列思路怕自己忘 計算區間和的問題,一般轉換為兩個字首和相減,所以我們先求出字首和sum i 表示前i項的和,那麼就轉化成了求 s r s l 1 列舉右端點,則問題變為 找到乙個左端點,i m j i 1 且 s j 最小 然後執行單調佇列的幾個步驟 判斷隊首與i的距離是否超過m的範圍,若...

一本通1549最大數

題目描述 原題來自 jsoi 2008 給定乙個正整數數列 a1 a2 a3 an 每乙個數都在 0 p 1 之間。可以對這列數進行兩種操作 程式執行的最開始,整數序列為空。寫乙個程式,讀入操作的序列,並輸出詢問操作的答案。輸入格式 第一行有兩個正整數 m,p,意義如題目描述 接下來 m 行,每一行...