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 }

你可能感兴趣的:(OS)