单调栈--poj3494 Largest Submatrix of All 1’s

给定01矩阵,求其中都为1的矩阵的最大面积。

想法很奇妙,先求每一行向上最多可以延伸多少,再对每一行对非0区域,用单调栈求区间最小值*区间长度,即为面积。

#include

#include

#include

#include

using namespacestd;

const int maxn =2000 + 5;


int m,n;//mn

struct node{

    int v,l,r;//v[l,r]内的最小值

};

stack<node> stk;

int ans = 0;

node cnt[maxn][maxn];

node t;

void clear_stk()

{

    while (!stk.empty()) {

        t =stk.top();stk.pop();

        ans =max(ans,t.v * (t.r - t.l +1));

        if(!stk.empty()){

            stk.top().r =t.r;

        }

    }

}

void solve()

{

    for (int i =1;i <= m ; i ++) {

        for (int j =1; j <= n; j ++) {

            if(!cnt[i][j].v) {clear_stk();}

            else {

                if(stk.empty() ||cnt[i][j].v >=stk.top().v)

                {

                    stk.push(cnt[i][j]);

                }

                else {

                    while (!stk.empty() &&cnt[i][j].v <stk.top().v) {

                        t =stk.top();stk.pop();

                        ans =max(ans,t.v * (t.r - t.l +1));

                        if(!stk.empty()){

                            stk.top().r =t.r;

                        }

                        cnt[i][j].l =t.l;

                    }

                    stk.push(cnt[i][j]);

                }

            }

        }

        clear_stk();

    }

}

int main()

{

    while (scanf("%d%d",&m,&n) != EOF) {

        ans =0;

        memset(cnt,0, sizeof(cnt));

        for (int i =1; i <= m; i ++) {

            for (int j =1; j <= n; j ++) {

                scanf("%d",&cnt[i][j].v);

                if(cnt[i][j].v)cnt[i][j].v =1 + cnt[i -1][j].v;

                cnt[i][j].l =cnt[i][j].r = j;

            }

        }

       

        solve();

        printf("%d\n",ans);

    }

    return0;

}



你可能感兴趣的:(单调栈&单调队列)