最大全1子矩陣

2021-06-25 23:37:32 字數 2799 閱讀 5490

題目描述:

在乙個m * n的矩陣中,所有的元素只有0和1,從這個矩陣中找出乙個面積最大的全1子矩陣,所謂最大是指元素1的個數最多。

輸入:輸入可能包含多個測試樣例。

對於每個測試案例,輸入的第一行是兩個整數m、n(1<=m、n<=1000):代表將要輸入的矩陣的大小。

矩陣共有m行,每行有n個整數,分別是0或1,相鄰兩數之間嚴格用乙個空格隔開。

輸出:對應每個測試案例,輸出矩陣中面積最大的全1子矩陣的元素個數。

樣例輸入:

2 2

0 00 0

4 40 0 0 0

0 1 1 0

0 1 1 0

0 0 0 0

樣例輸出:

0

4

方法是:

1、先將0/1矩陣讀入x,對每乙個非零元素x[i][j],將其更新為:在本行,它前面的連續的1的個數+1(+1表示算入自身)

比如,若某一行為0 1 1 0 1 1 1,則更新為0 1 2 0 1 2 3

2、對每乙個非零元素x[i][j],在第j列向上和向下掃瞄,直到遇到比自身小的數,若掃瞄了y行,則得到乙個大小為x[i][j]*(y+1)的全1子矩陣(+1表示算入自身所在行)

比如,若某一列為[0 3 4 3 5 2 1]'(方便起見,這裡將列表示成乙個列向量),我們處理這一列的第4個元素,也就是3,它向上可以掃瞄2個元素,向下可以掃瞄1個元素,於是得到乙個4×3的全1子矩陣。

3、在這些數值中取乙個最大的。

思想大概如下圖所示(空白處的0沒有標出)

對照步驟2中給出的例子,藍色的箭頭表示向上向下掃瞄,黑色的框表示最終得到的全1子矩陣

這樣做為什麼是對的?

想一想,對那個最大的全1子矩陣,用這種方法能不能找到它呢?——肯定可以。

乙個最大全1子矩陣,肯定是四個邊界中的每乙個都不能再擴充套件了,如下圖

假設圖中全1子矩陣就是最大子矩陣,則左邊界左側那一列肯定有乙個或多個0(否則就可以向左邊擴充套件一列,得到乙個更大的全1矩陣)

對其他3個邊界有類似的情況。

然後看圖中用黑圈標出的1(其特點是:和左邊界左側的某個0在同一行),從這個1出發,按照之前的方法,向上向下掃瞄,就可以得到這個子矩陣。所以,肯定可以找到。

下面是我的**,實際實現的時候,為了提高效率,估計了一下upperbound,這個upperbound就是:在當前列,

包含x[i][col]的連續的非零序列的和,比如對某列[0 3 4 3 5 2 1]',後面6個的upperbound都是

3 + 4 + 3 + 5 + 2 + 1 = 18,對於0元素,不需要upperbound

public class maxonematrix 

aux[i][j] = tmp+1;}}

} int max = integer.min_value;

for(int i=0; i=0; k--)

}} return max;

} public static void main(string args), , , };

system.out.println(counts(a));

}}

#include int

m, n;

int x[1002][1002

];int upperbound[1002][1002

];//

pre處理後,x[i][j]表示原矩陣第i行中x[i][j]前面有多少個連續的1

void

pre()

}}}//

proc_col對第col列計算每個x[i][col]的upperbound,這個upperbound就是:在當前列,

//包含x[i][col]的連續的非零序列的和,比如對[0 3 4 3 5 2 1],後面6個的upperbound都是

//3 + 4 + 3 + 5 + 2 + 1 = 18,對於0元素,不需要upperbound

void proc_col(int

col)

int sum = 0, j =i;

while (j < m && x[j][col] > 0

)

for (int k = i; k < j; k++)

i = j;//

之後i還會++,但是不會跳過重要的值,因為此時x[j]=0或在界外}}

//逐列計算upperbound

void

calc_upper()}//

從x[row][col]向上向下掃瞄

int search_up_down(int row, int

col)

else

}for (int i = row + 1; i < m; i++)

else

}return cnt *val;}//

得到最大全1子矩陣的大小

intgetmax() }}

}return

max;

}int main(int argc, const

char *argv)

}pre();

calc_upper();

printf(

"%d\n

", getmax());

}return0;

}

最大全1子矩陣

給出1個m n的矩陣m1,裡面的元素只有0或1,找出m1的乙個子矩陣m2,m2中的元素只有1,並且m2的面積是最大的。輸出m2的面積。input 第1行 2個數m,n中間用空格分隔 2 m,n 100 第2 n 1行 每行m個數,中間用空格分隔,均為0或1。output 輸出最大全是1的子矩陣的面積...

poj 3494 dp 最大全1子矩陣

題意 給定乙個n m大小的0 1矩陣,求所有元素都為1的最大子矩陣。思路 把2維轉化為一維 這一點有點像poj1050求最大子矩陣 列舉每一行。dp i j 的值表示第 i,j 個位置作為底,它上面的 包括自己 的連續1的個數。然後通過棧的單調性求每行的 最大值 每行的情況如同poj2559 可以用...

COCI NEO 單調棧求最大全1子矩陣

應該能進 現在有乙個n m的矩陣,定義乙個矩陣 r 2,c 2 是cool的當 a i j a i 1 j 1 a i j 1 a i 1 j 定義乙個矩陣是非常cool的,當所有它的子矩陣 r 2,c 2 是cool的。問你這個矩陣中非常cool 的矩陣最多包含的點的數量是多少。這個題意我搞了好久...