传送门:BZOJ1057
大水题(虽然我WA了status的一页)
不知道那些搞奇偶性的什么心态……
直接悬线法即可。
不要忘记判断当前点与上方点有无关系
代码上的小细节见下。
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int h[2005][2005],l[2005][2005],r[2005][2005];
int map[2005][2005];
int f[2005][2005];
int lo,ro;
int n,m;
int ans;
void First()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(i==1)
h[i][j]=1;
else
h[i][j]=map[i-1][j]==map[i][j]?1:h[i-1][j]+1;
for(int i=1;i<=n;i++){
lo=1;ro=m;
for(int j=1;j<=m;j++)
if(j==1)
l[i][j]=1;
else
if(map[i][j]==map[i][j-1])
l[i][j]=lo=j;
else
if(i==1||h[i][j]==1)
l[i][j]=lo;
else
l[i][j]=max(l[i-1][j],lo);
for(int j=m;j>=1;j--)
if(j==m)
r[i][j]=m;
else
if(map[i][j]==map[i][j+1])
r[i][j]=ro=j;
else
if(i==1||h[i][j]==1)
r[i][j]=ro;
else
r[i][j]=min(r[i-1][j],ro);
}
/*for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
printf("%d %d %d %d %d\n",i,j,l[i][j],r[i][j],h[i][j]);*/
}
void Solve()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
if(i==1||j==1||map[i-1][j]==map[i][j]||map[i][j-1]==map[i][j])
f[i][j]=1;
else
f[i][j]=min(min(f[i-1][j],f[i][j-1]),f[i-1][j-1])+1;
ans=max(ans,f[i][j]);
}
printf("%d\n",ans*ans);
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);
}
void Readdata()
{
freopen("loli.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&map[i][j]);
}
void Close()
{
fclose(stdin);
fclose(stdout);
}
int main()
{
Readdata();
First();
Solve();
Close();
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/le_ballon_rouge/article/details/48028819