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