[ZJOI2007]棋盘制作

[ZJOI2007]棋盘制作

题目链接 

题目梗概

这是一个提高+难度的题,但是感觉并配不上这个难度,主要想记一种矩形里面求最大子矩形的方法。

这个做法我称之为吊着的dailinzu法。

具体做法

具体来讲就是想象有一条条线吊着dailinzu然后对每个位置对齐,然后分别求出三个方向的线。这样就确定了一个位置的矩形,对其求面积即可。

然后嘞。就有一个问题,那就是如果最优解在障碍物下方,那么就会被扫掉。这也不要紧,因为要求的是矩形,因此这个解会被处于障碍正下方的那个点表示出来。

好啦

上代码

#include<bits/stdc++.h>
using namespace std;
int lefts[2005][2005],rights[2005][2005],graph[2005][2005],up[2005][2005];
int n,m;
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++){
            cin>>graph[i][j];
            lefts[i][j]=rights[i][j]=j;
            up[i][j]=1;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=2;j<=m;j++){
            if(graph[i][j]!=graph[i][j-1]){
                lefts[i][j]=lefts[i][j-1];
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=m-1;j>=1;j--){
            if(graph[i][j]!=graph[i][j+1])
                rights[i][j]=rights[i][j+1];
        }
    }
    int zheng=0,ju=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(graph[i][j]!=graph[i-1][j]&&i!=1){
                lefts[i][j]=max(lefts[i][j],lefts[i-1][j]);
                rights[i][j]=min(rights[i][j],rights[i-1][j]);    
                up[i][j]=up[i-1][j]+1;
            }
            int a=rights[i][j]-lefts[i][j]+1;
            int b=up[i][j];
            zheng=max(zheng,min(a,b)*min(a,b));
            ju=max(ju,a*b);
        }
    }
    cout<<zheng<<endl<<ju<<endl;
}
rush!
原文地址:https://www.cnblogs.com/LH2000/p/12494244.html