基准时间限制:1 秒 空间限制:131072 KB 分值: 80
难度:5级算法题
给出1个M*N的矩阵M1,里面的元素只有0或1,找出M1的一个子矩阵M2,M2中的元素只有1,并且M2的面积是最大的。输出M2的面积。
Input
第1行:2个数m,n中间用空格分隔(2 <= m,n <= 500) 第2 - N + 1行:每行m个数,中间用空格分隔,均为0或1。
Output
输出最大全是1的子矩阵的面积。
Input示例
3 3 1 1 0 1 1 1 0 1 1
Output示例
4
两种做法 一种暴力,一种技巧 ,技巧类似kmp吧 我是这样理解的
首先是暴力
#include <bits/stdc++.h>
using namespace std;
int tag[505][505];
int dp[505][505];
int main()
{
int n,m;
while(cin>>n>>m)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>tag[i][j];
if(tag[i][j]) dp[i][j]=dp[i][j-1]+1;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
//cout<<dp[i][j]<<' ';
}
// cout<<endl;
}
int k,maxs=0,l,x;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
x=dp[i][j];
k=i;
l=1;
while(k>0)
{
x=min(x,dp[k][j]);
maxs=max(maxs,x*l);
l++;
k--;
}
}
}
cout<<maxs<<endl;
}
}
然后技巧了 复杂度o(nm).
#include <bits/stdc++.h>
#define mo 1010
using namespace std;
int d[mo],a[mo][mo],l[mo],h[mo];
int main()
{
int n,m;
while(cin>>n>>m)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
int maxs=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]) d[j]++;
else d[j]=0;
}
for(int j=1;j<=m;j++)
{
l[j]=j;
while(l[j]>1&&d[j]<=d[l[j]-1])
{
l[j]=l[l[j]-1];
}
}
for(int j=m;j>0;j--)
{
h[j]=j;
while(h[j]<m&&d[j]<=d[h[j]+1])
{
h[j]=h[h[j]+1];
}
}
for(int j=1;j<=m;j++)
maxs=max(maxs,d[j]*(h[j]-l[j]+1));
}
cout<<maxs<<endl;
}
}