Vijos 1351 棋盘制作(DP)

题目链接

这种黑白问题,遇到好几次了,杭电1838和这个非常类似,这个题是他的加强版,不仅要求正方形还要求矩形的最大面积。

先是两个标记数组o1,o2标记颜色不同的最大长度。sq存在正方形的最大边长正方形的状态转移就是

if(p[i][j] == p[i-1][j-1])sq[i][j] = getmin(sq[i-1][j-1]+1,o1[i][j],o2[i][j]);

最复杂的是矩形的最大面积。

矩形分两种情况,一种是横着,一种是竖着放,开4个数组分别标记长宽。最后找最大就好。

写的有点繁琐。

PS:刚看了一下讨论区,我晕我的程序这么搓啊,内存多+程序跑的慢。。。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4 #define N 2001
  5 int p[N][N];
  6 int o1[N][N],o2[N][N],sq[N][N];
  7 int rex[N][N],rey[N][N],rx[N][N],ry[N][N];
  8 int getmin(int a,int b,int c)
  9 {
 10     int min;
 11     min = a;
 12     if(min > b)
 13     min = b;
 14     if(min > c)
 15     min = c;
 16     return min;
 17 }
 18 int min(int a,int b)
 19 {
 20     if(a > b)
 21     return b;
 22     else
 23     return a;
 24 }
 25 int main()
 26 {
 27     int n,m,i,j,max1,max2;
 28     scanf("%d%d",&n,&m);
 29     for(i = 1;i <= n;i ++)
 30     {
 31         for(j = 1;j <= m;j ++)
 32         {
 33             scanf("%d",&p[i][j]);
 34         }
 35     }
 36     o1[1][1] = o2[1][1] = 1;
 37     sq[1][1] = rex[1][1] = 1;
 38     rey[1][1] = 1;
 39     rx[1][1] = ry[1][1] = 1;
 40     for(i = 2;i <= m;i ++)
 41     {
 42         sq[1][i] = 1;
 43         rey[1][i] = 1;
 44         ry[1][i] = 1;
 45         if(p[1][i] != p[1][i-1])
 46         {
 47             o1[1][i] = o1[1][i-1]+1;
 48         }
 49         else
 50         {
 51             o1[1][i] = 1;
 52         }
 53         rex[1][i] = o1[1][i];
 54         rx[1][i] = o1[1][i];
 55         o2[1][i] = 1;
 56     }
 57     for(i = 2;i <= n;i ++)
 58     {
 59         sq[i][1] = 1;
 60         rex[i][1] = 1;
 61         rx[i][1] = 1;
 62         if(p[i][1] != p[i-1][1])
 63         {
 64             o2[i][1] = o2[i-1][1]+1;
 65         }
 66         else
 67         {
 68             o2[i][1] = 1;
 69         }
 70         rey[i][1] = o2[i][1];
 71         ry[i][1] = o2[i][1];
 72         o1[i][1] = 1;
 73     }
 74     for(i = 2;i <= n;i ++)
 75     {
 76         for(j = 2;j <= m;j ++)
 77         {
 78             if(p[i][j] != p[i][j-1])
 79             {
 80                 o1[i][j] = o1[i][j-1]+1;
 81             }
 82             else
 83             {
 84                 o1[i][j] = 1;
 85             }
 86             if(p[i][j] != p[i-1][j])
 87             {
 88                 o2[i][j] = o2[i-1][j]+1;
 89             }
 90             else
 91             {
 92                 o2[i][j] = 1;
 93             }
 94             if(p[i][j] != p[i][j-1])//竖着矩形状态转移
 95             {
 96                 ry[i][j] = min(ry[i][j-1],o2[i][j]);
 97                 rx[i][j] = rx[i][j-1]+1;
 98             }
 99             else
100             {
101                 ry[i][j] = o2[i][j];
102                 rx[i][j] = 1;
103             }
104             if(p[i][j] != p[i-1][j])//横着矩形状态转移
105             {
106                 rex[i][j] = min(rex[i-1][j],o1[i][j]);
107                 rey[i][j] = rey[i-1][j]+1;
108             }
109             else
110             {
111                 rex[i][j] = o1[i][j];
112                 rey[i][j] = 1;
113             }
114             if(p[i][j] == p[i-1][j-1])
115             {
116                 sq[i][j] = getmin(sq[i-1][j-1]+1,o1[i][j],o2[i][j]);
117             }
118             else
119             {
120                 sq[i][j] = 1;
121             }
122         }
123     }
124     max1 = max2 = 0;
125     for(i = 1;i <= n;i ++)
126     {
127         for(j = 1;j <= m;j ++)
128         {
129             if(max1 < sq[i][j])
130             max1 = sq[i][j];
131             if(max2 < rex[i][j]*rey[i][j])
132             max2 = rex[i][j]*rey[i][j];
133             if(max2 < rx[i][j]*ry[i][j])
134             max2 = rx[i][j]*ry[i][j];
135         }
136     }
137     printf("%d\n%d\n",max1*max1,max2);
138     return 0;
139 }
posted @ 2012-08-15 19:22  Naix_x  阅读(213)  评论(0编辑  收藏  举报