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

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

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

#include <iostream>

#include <cstdio>

#include <cstring>

#include <stack>

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;

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值