其他分享
首页 > 其他分享> > BZOJ-3039玉蟾宫(单调栈)

BZOJ-3039玉蟾宫(单调栈)

作者:互联网

题目描述

  求 \(n\) 行 \(m\) 列的 \(01\) 矩阵的最大全 \(1\) 子矩阵(\(1\leq n,m\leq 1000\))。

分析

  经典题。

  预处理出每个位置 \((i,j)\) 能向上扩展的最大值,用 $height[i][j] $表示。

  对于每一行的每个位置,向左右扩展最长的长度,即矩形的长,矩形的宽就是这一格的 \(height[i][j]\),所以向左右两边扩展的条件就是要扩展的那一格中的数字一定 $\geq $ 当前这一格的数字 $ height[i][j] $。

  时间复杂度 \(O(nm)\)。

代码

#include<bits/stdc++.h>
using namespace std;
int mp[1010][1010];
int height[1010][1010];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            char ch[2];
            scanf("%s",&ch);
            if (ch[0]=='F') mp[i][j]=1;
            if (ch[0]=='R') mp[i][j]=0;
        }
    }
    for(int j=1;j<=m;j++)
    {
        for(int i=1;i<=n;i++)
        {
            if(mp[i][j]==1)
                height[i][j]=height[i-1][j]+1;
            else
                height[i][j]=0;
        }
    }
    int maxn=0;
    for(int i=1;i<=n;i++)
    {
        int ans=0;
        for(int j=1;j<=m;j++)
        {
            int l=j,r=j;//左边能扩展到的最远位置和右边能扩展到的最远位置
            while(l>=1&&height[i][l]>=height[i][j])
                l--;
            l++;
            while(r<=m&&height[i][r]>=height[i][j])
                r++;
            r--;
            ans=max(ans,height[i][j]*(r-l+1));
        }
        maxn=max(maxn,ans);
    }
    cout<<3*maxn<<endl;
    return 0;
}

标签:3039,玉蟾,int,扩展,height,ans,1010,这一格,BZOJ
来源: https://www.cnblogs.com/DestinHistoire/p/13973153.html