[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!