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 }