洛谷 P1169 [ZJOI2007]棋盘制作

Posted Neptune

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P1169 [ZJOI2007]棋盘制作相关的知识,希望对你有一定的参考价值。

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 }

 

以上是关于洛谷 P1169 [ZJOI2007]棋盘制作的主要内容,如果未能解决你的问题,请参考以下文章

[luogu]P1169 [ZJOI2007]棋盘制作[DP][单调栈]

P1169 [ZJOI2007]棋盘制作

P1169 [ZJOI2007]棋盘制作

P1169 [ZJOI2007]棋盘制作

P1169 [ZJOI2007]棋盘制作

[ZJOI2007]棋盘制作