題目描述:
在乙個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 intm, 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 的矩陣最多包含的點的數量是多少。這個題意我搞了好久...