-
题目描述:
-
在一个M * N的矩阵中,所有的元素只有0和1,从这个矩阵中找出一个面积最大的全1子矩阵,所谓最大是指元素1的个数最多。
-
输入:
-
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行是两个整数m、n(1<=m、n<=1000):代表将要输入的矩阵的大小。
矩阵共有m行,每行有n个整数,分别是0或1,相邻两数之间严格用一个空格隔开。
-
输出:
-
对应每个测试案例,输出矩阵中面积最大的全1子矩阵的元素个数。
-
样例输入:
-
2 2 0 0 0 0 4 4 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0
-
样例输出:
-
0 4
//动态规划求最大矩形面积,分行处理,以每行每列为高,动态找在该行找左右的最大区间段,然后算出面积,记录最大值
#include<iostream>
#include<string>
#include<cstdio>
using namespace std;
#define MAX 1000+10
int height[MAX][MAX];
int right_dis[MAX];
int left_dis[MAX];
int main()
{
int n,m,i,j,temp,max;
while(cin>>n>>m)
{
// memset(height,0,sizeof(height));
for(i=1;i<=m;i++)
height[0][i]=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
scanf("%d",&temp);
//求出每个位置的高度
if(temp==1)
height[i][j]=height[i-1][j]+1;
else
height[i][j]=0;
}
}
max=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
temp=j;
while(temp>1&&height[i][j]<=height[i][temp-1])
temp=left_dis[temp-1];
left_dis[j]=temp;
}
for(j=m;j>=1;j--)
{
temp=j;
while(temp<m&&height[i][j]<=height[i][temp+1])
temp=right_dis[temp+1];
right_dis[j]=temp;
}
for(j=1;j<=m;j++)
{
temp=(right_dis[j]-left_dis[j]+1)*height[i][j];
if(temp>max)
max=temp;
}
}
cout<<max<<endl;
}
return 0;
}