Largest Submatrix of All 1’s POJ - 3494(单调栈)

Given a m-by-n (0,1)-matrix, of all its submatrices of all 1’s which is the largest? By largest we mean that the submatrix has the most elements.

Input

The input contains multiple test cases. Each test case begins with m and n (1 ≤ m,n ≤ 2000) on line. Then come the elements of a (0,1)-matrix in row-major order on mlines each with n numbers. The input ends once EOF is met.

Output

For each test case, output one line containing the number of elements of the largest submatrix of all 1’s. If the given matrix is of all 0’s, output 0.

Sample Input
2 2
0 0
0 0
4 4
0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0
Sample Output
0

4

题意: 
给出一个nm的01矩阵,求出最大全1子矩阵面积。 
数据范围:n,m2000 

思路 :如果把每一行看做底,在每一行里,就可以求该行最大矩形,所以遍历所有行,就能遍历所有矩形。 我们把每一行单独处理,把从这行向上连续延伸全为1的最大长度看成是矩形的高,那么每行其实就是求个最大矩形面积。 h[i][j]表示 i 行时矩形的高度。和http://blog.csdn.net/sunmoonvocano/article/details/75268726 这个题类似只

变成了二维的而已,原理相同,很多单调站的题都是这个写法。

#include 
#include 
#include 
#include 
using namespace std;

const int maxn = 2100;
int a[maxn][maxn]; // 存数据
int l[maxn] ,r[maxn]; // 记录每行每元素左右边界
int h[maxn][maxn]; // 记录每个位置矩形高度
int main()
{
    int m,n;
    int max_;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        max_ = -1;
        for(int i = 1; i <= m; i++)
        for(int j = 1; j <= n; j++)
        {
            scanf("%d",&a[i][j]);
            if(a[i][j] == 0) h[i][j] = 0;
            else h[i][j] = h[i-1][j] + 1;
        }
        for(int i = 1; i <= m; i++) // 遍历行
        {
            stack  s;
            for(int j = 1; j <= n; j++)  //第i 行每个元素左边界
            {
                while(!s.empty() && h[i][j] <= h[i][s.top()])
                    s.pop();
                l[j] = s.empty() ? 1 : s.top() + 1;
                s.push(j);
            }
            stack  s1;
            for(int j = n; j >= 1; j--)  //第i 行每个元素右边界
            {
                while(!s1.empty() && h[i][j] <= h[i][s1.top()])
                    s1.pop();
                r[j] = s1.empty() ? n : s1.top() - 1;
                s1.push(j);
            }
            for(int j = 1; j <=n ; j++)
            {
                int size_ = (r[j]-l[j]+1) * h[i][j];
                max_ = max(max_,size_);
            }
        }
        printf("%d\n",max_);
    }
    return 0;
}


[i][j]:ij1

你可能感兴趣的:(数据结构)