设$lt[i][j]$为向左最远到达的点,$rt$同理,$ht[i][j]$为向上最远扩展多高
一开始先设初值为自己位置,高度为1
预处理每个点左右扩展的范围,扩展条件根据题目决定
然后可以dp:
lt[i][j]=max(lt[i][j],lt[i-1][j]);
rt[i][j]=min(rt[i][j],rt[i-1][j]);
ht[i][j]=ht[i-1][j]+1;
具体可以看其他的博客
#include<bits/stdc++.h> using namespace std; const int maxn=2009; int n,m,ans1,ans2; int lt[maxn][maxn],rt[maxn][maxn],ht[maxn][maxn],mp[maxn][maxn]; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ scanf("%d",&mp[i][j]); lt[i][j]=rt[i][j]=j; ht[i][j]=1; } for(int i=1;i<=n;i++) for(int j=2;j<=m;j++) if(mp[i][j]!=mp[i][j-1]) lt[i][j]=lt[i][j-1]; for(int i=1;i<=n;i++) for(int j=m-1;j>=1;j--) if(mp[i][j]!=mp[i][j+1]) rt[i][j]=rt[i][j+1]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ if(i>1 && mp[i][j] !=mp[i-1][j]){ lt[i][j]=max(lt[i][j],lt[i-1][j]); rt[i][j]=min(rt[i][j],rt[i-1][j]); ht[i][j]=ht[i-1][j]+1; } int a=rt[i][j]-lt[i][j]+1; int b=min(a,ht[i][j]); ans1=max(ans1,b*b); ans2=max(ans2,a*ht[i][j]); } printf("%d\n%d",ans1,ans2); }