题目来源:https://www.luogu.org/problem/show?pid=1169#sub
类似此题的处理方法:http://blog.csdn.net/moon_sky1999/article/details/52944272
没有用什么高级的算法,只是朴素的dp。
定义数组h[i][j]表示以点i,j处的最大高度,r[i][j]表示从点i,j开始向左扩展最多扩展多少位,l[i][j]表示向左扩展多少位。
最大矩形为max(h[i][j]*(l[i][j]+r[i][j]-1))。
详见代码:
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <cstring>
using namespace std;
int a[2003][2003];
int h[2003][2003],l[2003][2003],r[2003][2003];
int main()
{
ios::sync_with_stdio(false);
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]!=a[i-1][j])h[i][j]=h[i-1][j]+1;
else h[i][j]=1;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
l[i][j]=1;
if(a[i][j]!=a[i][j-1])
{
int t=j-1;
while(h[i][t]>=h[i][j]&&a[i][t]!=a[i][t+1]&&t>=1)
{
l[i][j]+=l[i][t];
t-=l[i][t];
}
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=m;j>=1;j--)
{
r[i][j]=1;
if(a[i][j]!=a[i][j+1])
{
int t=j+1;
while(a[i][t]!=a[i][t-1]&&h[i][t]>=h[i][j]&&t<=m)
{
r[i][j]+=r[i][t];
t+=r[i][t];
}
}
}
}
int w=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int c=l[i][j]+r[i][j]-1,e=h[i][j];
w=max(w,min(c,e)*min(c,e));
}
}
cout<<w<<endl;
w=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int c=l[i][j]+r[i][j]-1,e=h[i][j];
w=max(w,c*e);
}
}
cout<<w;
return 0;
}