luoguP1169 [ZJOI2007]棋盘制作

单调栈优化dp。和找最大矩阵面积差不多。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2010;
bool a[maxn][maxn];
int up[maxn][maxn],ans1=0,ans2=0;//ans1=正方形 ans2=矩形 
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]);
            if(i==1||a[i-1][j]!=a[i][j]){
                up[i][j]=up[i-1][j]+1;
            }
            else up[i][j]=1;
        }
    }
    for(int i=1;i<=n;++i){
        int st[maxn],l[maxn],r[maxn],top=0;st[0]=0;
        for(int j=1;j<=m;++j){
            if(j!=1&&a[i][j-1]==a[i][j])st[0]=j-1,top=0;
            while(top&&up[i][st[top]]>=up[i][j])--top;
            l[j]=st[top]+1;
            st[++top]=j;
        }
        top=0;st[0]=m+1;
        for(int j=m;j>=1;--j){
            if(j!=m&&a[i][j]==a[i][j+1])st[0]=j+1,top=0;
            while(top&&up[i][st[top]]>=up[i][j])--top;
            r[j]=st[top]-1;
            st[++top]=j;
        }
        for(int j=1;j<=m;++j){
            int t=min(r[j]-l[j]+1,up[i][j]);
            ans1=max(ans1,t*t);
            ans2=max(ans2,(r[j]-l[j]+1)*up[i][j]);
        }
    }
    printf("%d\n%d",ans1,ans2);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Dream-Runner/p/9427959.html