黑暗爆炸OJ#1057. [ZJOI2007]棋盘制作(悬线法)
https://darkbzoj.tk/problem/1057
这个与有障碍格子的悬线法有一点区别
当亲格子不能延续时,当前格子依然有用
#include<bits/stdc++.h> using namespace std; #define N 2003 int a[N][N]; int h[N],l[N],r[N]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) scanf("%d",&a[i][j]); for(int i=1;i<=m;++i) { a[0][i]=-1; l[i]=1; r[i]=m; } for(int i=1;i<=n;++i) a[i][0]=a[i][m+1]=-1; int t1=0,t2=0,L,R; for(int i=1;i<=n;++i) { L=0; for(int j=1;j<=m;++j) if(a[i][j]!=a[i-1][j] && a[i][j]!=a[i][j+1] && a[i][j]!=a[i][j-1]) ++h[j]; else h[j]=1; for(int j=1;j<=m;++j) if(a[i][j]!=a[i-1][j] && a[i][j]!=a[i][j-1]) l[j]=max(l[j],L); else { l[j]=1; L=j; } R=m+1; for(int j=m;j;--j) if(a[i][j]!=a[i-1][j] && a[i][j]!=a[i][j+1]) r[j]=min(r[j],R); else { r[j]=m; R=j; } for(int j=1;j<=m;++j) { t2=max(t2,(r[j]-l[j]+1)*h[j]); t1=max(t1,min(r[j]-l[j]+1,h[j])*min(r[j]-l[j]+1,h[j])); } } printf("%d\n%d",t1,t2); }