【DP专题】——洛谷P1169棋盘制作

悬线法。

传送门:GO


设l[i][j],r[i][j],up[i][j]表示能向左延伸的最远位置,向右延伸的最远位置,上方的最长距离。

预处理一下l和r,n方更新即可。

其余很好懂,看代码吧。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int read(){
 4     int x=0,f=1;
 5     char c=getchar();
 6     while(!isdigit(c)){
 7         if(c=='-') f=-1;
 8         c=getchar();
 9     }
10     while(isdigit(c)){
11         x=x*10+c-'0';
12         c=getchar();
13     }
14     return x*f;
15 }
16 const int N=2010;
17 int n,m,ans1,ans2,c,d;
18 bool a[N][N];
19 int l[N][N],r[N][N],up[N][N];
20 int main(){
21     n=read();m=read();
22     for(int i=1;i<=n;i++){
23         for(int j=1;j<=m;j++){
24             a[i][j]=read();
25             l[i][j]=r[i][j]=j;
26             up[i][j]=1;
27         }
28     }
29     for(int i=1;i<=n;i++){
30         for(int j=2;j<=m;j++){
31             if(a[i][j]!=a[i][j-1]) l[i][j]=l[i][j-1];
32         }
33         for(int j=m-1;j>=1;j--){
34             if(a[i][j]!=a[i][j+1]) r[i][j]=r[i][j+1];
35         }
36     }
37     for(int i=1;i<=n;i++){
38         for(int j=1;j<=m;j++){
39             if(a[i][j]!=a[i-1][j]&&i>1){
40                 l[i][j]=max(l[i][j],l[i-1][j]);
41                 r[i][j]=min(r[i][j],r[i-1][j]);
42                 up[i][j]=up[i-1][j]+1;
43             }
44             c=r[i][j]-l[i][j]+1;
45             d=min(c,up[i][j]);
46             ans1=max(d*d,ans1);
47             ans2=max(c*up[i][j],ans2);
48         }
49     }
50     printf("%d\n%d",ans1,ans2);
51     return 0;
52 }

猜你喜欢

转载自www.cnblogs.com/Nelson992770019/p/11581379.html