P5943 [POI2002] 最大的园地
题意
首先给定一个整数
思路
先
优化1
当当前横向长度为
证明:很显然,面积为
优化2(重点)
当当前横向长度乘上竖直长度后仍小于等于
证明:再往下遍历只会让横向长度单调不上升,当前子矩阵面积不可能更大。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;//好习惯。
ll n,m,a[2001][2001],cnt,ans;
ll f[2001][2001];//记录点(i,j)左边(包括自己)有多少个连续的0。
ll s;//当前子矩阵横向长度。
inline ll read()
{
ll k=0,f=0;char c=getchar();
for(;!isdigit(c);c=getchar()) f|=c=='-';
for(;isdigit(c);c=getchar()) k=(k<<1)+(k<<3)+(c^48);
return f?-k:k;
}
int main()
{
n=read();
for(ll i=1;i<=n;i++)
{
for(ll j=1;j<=n;j++)
{
a[i][j]=read();
}
}
for(ll i=1;i<=n;i++)
{
cnt=0;
for(ll j=1;j<=n;j++)
{
if(!a[i][j]) cnt++;
else cnt=0;
f[i][j]=cnt;
}
}
for(ll i=1;i<=n;i++)
{
for(ll j=1;j<=n;j++)
{
s=f[i][j];
ans=max(ans,s);
for(ll l=i+1;l<=n;l++)
{
s=min(s,f[l][j]);
if(!s) break;//优化1。
if(s*(n-i+1)<=ans) break;//优化2。
ans=max(ans,s*(l-i+1));
}
}
}
cout<<ans;
return 0;
}