POJ1964 City Game
城市毒瘤。
求最大子矩阵,我首先考虑行列分开,觉得正解码量有点大就没想写。然后考虑前缀和/DP,发现也不行,最后无奈分析了一波复杂度,开始写正解。中间抄了一下之前写的一题的代码,然后WA了...原因是扫第二遍的时候减号左右两边写反了,还有就是一些奇奇怪怪的小细节,重新写一遍就A了。
1 #include <cstdio> 2 const int N = 1010; 3 4 int G[N][N], upto[N][N], l[N], temp[N], Q[N], top; 5 6 inline void max(int &a, int b) { 7 if(a < b) a = b; 8 return; 9 } 10 inline void min(int &a, int b) { 11 if(a > b) a = b; 12 return; 13 } 14 15 inline int solve(int n) { 16 //printf("temp: "); 17 //for(int i = 1; i <= n; i++) 18 for(int i = 1; i <= n + 1; i++) { 19 Q[++top] = i; 20 while(temp[Q[top - 1]] > temp[i]) { 21 l[Q[top - 1]] = i - Q[top - 1] - 1; 22 Q[top - 1] = Q[top--]; 23 } 24 } 25 top = 0; 26 for(int i = n; i >= 0; i--) { 27 Q[++top] = i; 28 while(temp[Q[top - 1]] > temp[i]) { 29 l[Q[top - 1]] += Q[top - 1] - i; 30 Q[top - 1] = Q[top--]; 31 } 32 } 33 int ans = 0; 34 for(int i = 1; i <= n; i++) { 35 max(ans, l[i] * temp[i]); 36 } 37 return ans; 38 } 39 40 int main() { 41 int T; 42 scanf("%d", &T); 43 while(T--) { 44 int m, n; 45 char c; 46 scanf("%d%d", &n, &m); 47 48 top = temp[n + 1] = 0; 49 50 for(int i = 1; i <= n; i++) { 51 for(int j = 1; j <= m; j++) { 52 c = getchar(); 53 while(c != 'R' && c != 'F') { 54 c = getchar(); 55 } 56 //putchar(c); 57 G[i][j] = (c == 'R') ? 1 : 0; 58 } 59 } 60 //printf("in over\n"); 61 for(int j = 1; j <= m; j++) { 62 int t = n + 1; 63 for(int i = n; i >= 1; i--) { 64 if(G[i][j]) { 65 t = i; 66 } 67 upto[i][j] = t; 68 } 69 } 70 /* 71 for(int i = 1; i <= n; i++) { 72 for(int j = 1; j <= m; j++) { 73 printf("%d ", upto[i][j]); 74 } 75 printf("\n"); 76 } 77 */ 78 int now, ans = 0; 79 for(int i = 1; i <= n; i = i + now + 1) { 80 now = n; 81 for(int j = 1; j <= m; j++) { 82 temp[j] = upto[i][j] - i; 83 min(now, temp[j]); 84 } 85 /* 86 printf("%d %d \n", i, now); 87 for(int j = 1; j <= m; j++) { 88 printf("%d ", temp[j]); 89 } 90 puts(""); 91 */ 92 int p = solve(m); 93 //printf("ans = %d \n", p); 94 max(ans, p); 95 } 96 printf("%d\n", ans * 3); 97 } 98 99 return 0; 100 }