最大子矩陣

2021-08-19 17:49:27 字數 1800 閱讀 6473

4.最大子矩陣

【題目描述】

給你乙個 n*m 的 01 矩陣,每次你可以交換任意兩列,你可以交換無限多次。你要通過

交換操作,求出最大的全 1 子矩陣的面積,所謂面積就是指包含的 1 的個數。

【輸入檔案】

第一行兩個正整數 n 和 m。

接下來 n 行,每行包含 m 個字元』0』或』1』,描述乙個矩陣。

【輸出檔案】

輸出僅一行,為最終的最大全 1 子矩陣的面積。

【樣例輸入】

10 6

001010

111110

011110

111110

011110

111111

110111

110111

000101

010101

【樣例輸出】

21【樣例解釋】

你可以通過交換,將 2,4,5 三列交換至相鄰位置,行從 2-8,列為 2,4,5 三列,所以

答案為 7*3=21。

【資料規模】

對於 10%的資料,1<=m<=5;

另有 20%的資料,1<=n,m<=1024;

對於 100%的資料,1<=n<=15000,1<=m<=1500;

題解:這題思路很神奇啊。

對於m很小的資料,我們直接m!階乘列舉列的可能,然後套用經典的最大子矩陣的o(n*m)的演算法就行了。

我們逐行考慮,對於每一行的m個位置,都可以得到它向上延伸的連續的』1』的個數,我們稱之為」高度」;顯然,如果我們將該行的高度從大到小排序,那麼從左往右掃一遍就可以統計出以該行為底邊的最大子矩陣的面積了。於是,我們就可以得到乙個o(n*m*log(m))的演算法了;我們對它進行優化,考慮到當行增加1以後,高度要麼增加1,要麼變成0,於是我們將變成0的高度放到最後就行了,用兩個指標實現就可以了,時間複雜度o(n*m)

**:

const

maxm =1505;

var s :ansistring;

a,b,h,p :array[0..maxm] of longint;

n,m,i,j :longint;

ans,cnt,dnt,t :longint;

begin

assign(input,'logs.in');reset(input);

assign(output,'logs.out');rewrite(output);

readln(n,m);

ans:=0;

for j:=1 to m do p[j]:=j;

for i:=1 to n do

begin

readln(s);

cnt:=0;

dnt:=m+1;

for j:=1 to m do

if s[p[j]]='1' then

begin

inc(cnt);

a[cnt]:=h[j]+1;

b[cnt]:=p[j];

if cnt*a[cnt]>ans then ans:=cnt*a[cnt];

end else

begin

dec(dnt);

a[dnt]:=0;

b[dnt]:=p[j];

end;

move(a,h,6008);

move(b,p,6008);

end;

writeln(ans);

close(input);close(output);

end.

最大子矩陣

描述 已知矩陣的大小定義為矩陣中所有元素的和。給定乙個矩陣,你的任務是找到最大的非空 大小至少是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的矩陣。輸入的第...

最大子矩陣

已知矩陣的大小定義為矩陣中所有元素的和。給定乙個矩陣,你的任務是找到最大的非空 大小至少是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的矩陣。輸入的第一行給...

最大子矩陣

描述 已知矩陣的大小定義為矩陣中所有元素的和。給定乙個矩陣,你的任務是找到最大的非空 大小至少是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。分析 首先,對矩陣預處理一下,將這個...