2016-05-31 14:56:17
题目链接: 洛谷 P1169 [ZJOI2007]棋盘制作
题目大意:
给定一块矩形,求出满足棋盘式黑白间隔的最大矩形大小和最大正方形大小
解法:
神犇王知昆的悬线法
H[i][j]表示(i,j)向上最长连续多少距离不出现障碍点(悬线)
L[i][j]表示H[i][j]这根悬线最多可以向左移到什么位置
R[i][j]表示H[i][j]这根悬线最多可以向右移到什么位置
递推方式看代码吧,很好理解的
1 //棋盘制作 (ZJOI2007) 2 //悬线法 矩形DP 3 #include<stdio.h> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=2010; 7 int H[maxn][maxn]; 8 int L[maxn][maxn]; 9 int R[maxn][maxn]; 10 bool map[maxn][maxn]; 11 int N,M; 12 int ans1; 13 int ans2; 14 int main() 15 { 16 scanf("%d %d",&N,&M); 17 for(int i=1;i<=N;i++) 18 { 19 for(int j=1;j<=M;j++) 20 { 21 int x; 22 scanf("%d",&x); 23 map[i][j]=x; 24 if(i==1)H[i][j]=1; 25 else if(map[i][j]!=map[i-1][j])H[i][j]=H[i-1][j]+1; 26 else H[i][j]=1; 27 } 28 } 29 for(int i=1;i<=N;i++) 30 { 31 for(int j=1;j<=M;j++) 32 { 33 L[i][j]=j; 34 while(L[i][j]>1&&map[i][L[i][j]-1]!=map[i][L[i][j]]&&H[i][L[i][j]-1]>=H[i][j]) 35 { 36 L[i][j]=L[i][L[i][j]-1]; 37 } 38 } 39 for(int j=M;j>=1;j--) 40 { 41 R[i][j]=j; 42 while(R[i][j]<M&&map[i][R[i][j]+1]!=map[i][R[i][j]]&&H[i][R[i][j]+1]>=H[i][j]) 43 { 44 R[i][j]=R[i][R[i][j]+1]; 45 } 46 } 47 for(int j=1;j<=M;j++) 48 { 49 int dx=R[i][j]-L[i][j]+1; 50 int dy=H[i][j]; 51 ans1=max(ans1,dx*dy); 52 ans2=max(ans2,min(dx,dy)*min(dx,dy)); 53 } 54 } 55 printf("%d\n%d",ans2,ans1); 56 }
时间: 2024-12-14 13:38:25