题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4328
用dp求图中包含的最大矩阵的问题。
此题可以看着是hdu 1505 City Game 的加强版
View Code
1 # include<stdio.h> 2 # include<string.h> 3 # include<stdlib.h> 4 # define N 1005 5 char map[N][N]; 6 int uR[N],uB[N],OB[N],OR[N],l[N],r[N]; 7 /* 8 uR[j]表示第j个字符上面有多少个R 9 uB[j]表示第j个字符上面有多少个B 10 OB[j]表示第奇数个字符上面有多少个B,第偶数个字符上面有多少个R 11 OR[j]表示第奇数个字符上面有多少个R,第偶数个字符上面有多少个B 12 每一个数组都会构成一个柱形图,求这个柱形图包含的最大矩形。 13 l,r分别记录当前柱向两边延展时最先遇到的比它低的。 14 */ 15 int main() 16 { 17 int i,j,n,m,ncase,t; 18 int circu,ans1,ans2,ans; 19 int mm; 20 scanf("%d",&ncase); 21 for(t=1;t<=ncase;t++) 22 { 23 scanf("%d%d",&n,&m); 24 for(i=1;i<=n;i++) 25 scanf("%s",map[i]+1); 26 memset(uR,0,sizeof(uR)); 27 memset(uB,0,sizeof(uB)); 28 memset(OB,0,sizeof(OB)); 29 memset(OR,0,sizeof(OR)); 30 circu=4; 31 for(i=1;i<=n;i++) 32 { 33 for(j=1;j<=m;j++) 34 { 35 if(map[i][j]=='B') 36 { 37 uR[j]=0; 38 uB[j]++; 39 if(j%2==1) 40 { 41 OB[j]=OR[j]+1; 42 OR[j]=0; 43 } 44 else 45 { 46 OR[j]=OB[j]+1; 47 OB[j]=0; 48 } 49 } 50 else 51 { 52 uR[j]++; 53 uB[j]=0; 54 if(j%2==1) 55 { 56 OR[j]=OB[j]+1; 57 OB[j]=0; 58 } 59 else 60 { 61 OB[j]=OR[j]+1; 62 OR[j]=0; 63 } 64 } 65 } 66 for(j=1;j<=m;j++) 67 { 68 if(uR[j]==0) continue; 69 mm=j-1; 70 while(uR[mm]>=uR[j]) mm=l[mm]; 71 l[j]=mm; 72 } 73 for(j=m;j>=1;j--) 74 { 75 if(uR[j]==0) continue; 76 mm=j+1; 77 while(uR[mm]>=uR[j]) mm=r[mm]; 78 r[j]=mm; 79 } 80 for(j=1;j<=m;j++) 81 { 82 if(uR[j]==0) continue; 83 ans1=l[j]; 84 ans2=r[j]; 85 ans=(ans2-ans1-1)*2+uR[j]*2; 86 if(ans>circu) circu=ans; 87 } 88 89 for(j=1;j<=m;j++) 90 { 91 if(uB[j]==0) continue; 92 mm=j-1; 93 while(uB[mm]>=uB[j]) mm=l[mm]; 94 l[j]=mm; 95 } 96 for(j=m;j>=1;j--) 97 { 98 if(uB[j]==0) continue; 99 mm=j+1; 100 while(uB[mm]>=uB[j]) mm=r[mm]; 101 r[j]=mm; 102 } 103 for(j=1;j<=m;j++) 104 { 105 if(uB[j]==0) continue; 106 ans1=l[j]; 107 ans2=r[j]; 108 ans=(ans2-ans1-1)*2 + uB[j]*2; 109 if(ans>circu) circu=ans; 110 } 111 112 for(j=1;j<=m;j++) 113 { 114 if(OR[j]==0) continue; 115 mm=j-1; 116 while(OR[mm]>=OR[j]) mm=l[mm]; 117 l[j]=mm; 118 } 119 for(j=m;j>=1;j--) 120 { 121 if(OR[j]==0) continue; 122 mm=j+1; 123 while(OR[mm]>=OR[j]) mm=r[mm]; 124 r[j]=mm; 125 } 126 for(j=1;j<=m;j++) 127 { 128 if(OR[j]==0) continue; 129 ans1=l[j]; 130 ans2=r[j]; 131 ans=(ans2-ans1-1)*2 + OR[j]*2; 132 if(ans>circu) circu=ans; 133 } 134 135 for(j=1;j<=m;j++) 136 { 137 if(OB[j]==0) continue; 138 mm=j-1; 139 while(OB[mm]>=OB[j]) mm=l[mm]; 140 l[j]=mm; 141 } 142 for(j=m;j>=1;j--) 143 { 144 if(OB[j]==0) continue; 145 mm=j+1; 146 while(OB[mm]>=OB[j]) mm=r[mm]; 147 r[j]=mm; 148 } 149 for(j=1;j<=m;j++) 150 { 151 if(OB[j]==0) continue; 152 ans1=l[j]; 153 ans2=r[j]; 154 ans=(ans2-ans1-1)*2 + OB[j]*2; 155 if(ans>circu) circu=ans; 156 } 157 } 158 printf("Case #%d: %d\n",t,circu); 159 } 160 return 0; 161 }