Largest Submatrix of All 1’s

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 mand n (1 ≤ mn ≤ 2000) on line. Then come the elements of a (0,1)-matrix in row-major order on m lines 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

如果對每個值都水平豎直方向找的話肯定會超時的

所以可以想到 把1改成它的高度 這樣光水平方向找就可以了

0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0
改成

0 0 0 0

0 1 1 0

0 2 2 0

0 0 0 0

接下來又和

        poj2796 feel good 單調棧 前後延伸                              

很像了 這次是隻要左右兩邊>=它就可以延伸 

只不過這次只需要區間長度 所以可以讓對應的j座標入棧 

構造單增棧 最後一列置爲-1保證元素全彈出

如果棧空 說明他是目前最小的 之前的都比他大 所以寬度就等於j  

否則寬度爲j-s.top()-1 s.top()是前面比他小的元素的座標 因爲座標從0開始所以減1

#include <iostream>
#include<stack>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=2010;
int a[maxn][maxn];
int b[maxn][maxn];
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=-1)
    {
        memset(b,0,sizeof(b));


        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            scanf("%d",&a[i][j]);
        }
        for(int i=0;i<n;i++) //另一個矩陣
        {
            for(int j=0;j<m;j++)
            {
                if(a[i][j]==0)b[i][j]=0;
                else
                {
                    if(i==0)b[i][j]=a[i][j];
                    else b[i][j]=a[i][j]+b[i-1][j];
                }
            }
        }
         int j;
        for(int i=0;i<n;i++)
        b[i][m]=-1;
        int mmax=-999;
        for(int i=0;i<n;i++)
        {
            stack<int>s;
            for(int j=0;j<=m;j++)
            {
                if(s.empty()||b[i][j]>b[i][s.top()])
                {
                    s.push(j);
                }
                else
                {
                    int tmp=s.top();
                    s.pop();
                    int w;
                    if(s.empty())
                    {
                        w=j;
                    }
                    else w=j-s.top()-1;
                    int ans=b[i][tmp]*w;
                    mmax=max(ans,mmax);
                    j--; //元素成功入棧時纔去下一個j
                }
            }
        }
        printf("%d\n",mmax);


    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章