您的位置:首页 > 其它

POJ - 3494 Largest Submatrix of All 1’s(单调栈)

2017-07-15 16:03 471 查看
点我看题

题意:给出n*m的0-1矩阵,找出0-1矩阵中由1组成的最大子矩阵.

分析:先根据输入的矩阵来初始化每个点的高度,对于第一行来说,h[1][j]就为当前mp[i][j]的值,对于其他行,如果点为0,那么高度为0,否则高度为前面的点的高度加1.然后利用单调栈来求每个点能涉及到的左右范围,最后求出最大面积即可.

参考代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<iostream>

using namespace std;
const int maxn = 2e3+10;
int n,m;
int mp[maxn][maxn];
int l[maxn][maxn],r[maxn][maxn];
int h[maxn][maxn];
int s[maxn];

int main()
{
while( ~scanf("%d%d",&n,&m))
{
for( int i = 1; i <= n; i++)
{
for( int j = 1; j <= m; j++)
{
scanf("%d",&mp[i][j]);
if(i == 1 || mp[i][j] == 0)
h[i][j] = mp[i][j];
else
h[i][j] = h[i-1][j]+mp[i][j];//求每一排当前点的最大高度
l[i][j] = r[i][j] = j;//初始化当前点的宽为自己
}
}

stack<int> s;
for(int i = 1; i <= n; i++)
{
while( !s.empty())
s.pop();
for( int j = 1; j <= m; j++)
{
while( !s.empty() && h[i][j] <= h[i][s.top()])
s.pop();
if( !s.empty())
l[i][j] = s.top()+1;
else
l[i][j] = 1;
s.push(j);
}
}

for( int i = 1; i <= n; i++)
{
while( !s.empty())
s.pop();
for( int j = m; j >= 1; j--)
{
while( !s.empty() && h[i][j] <= h[i][s.top()])
s.pop();
if( !s.empty())
r[i][j] = s.top()-1;
else
r[i][j] = m;
s.push(j);
}
}

int ans = 0;
for( int i = 1; i <= n; i++)
{
for( int j = 1; j <= m; j++)
ans = max(ans,(r[i][j]-l[i][j]+1)*h[i][j]);
}
printf("%d\n",ans);

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: