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

点我看题

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

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

参考代码:

#include
#include
#include
#include
#include
#include

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 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;
}



你可能感兴趣的:(数据结构--单调栈和单调队列)