小记:思路不对,努力白费
思路:同1506一样,一行一样的算,当算到某一行时,我们可以将这一行以及以上的所有行,看成是1506的样子,即这一行每个点都能形成的最大矩形是多大,
计算方法和1506一样,每个点记录左起和右起连续最长的长度.而高度,则是对每一行的每一点记录从第一行开始时到当前这一行,在当前这一点往上不碰到R的最大值
高度就相当于1506的高度。 因此问题转化了过来,只不过变成了个二维的问题。
老实说,我也没想到可以变成这个样子. 这个转化的能力还有待提高.
code:
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> using namespace std; #define mst(a,b) memset(a,b,sizeof(a)) #define REP(a,b,c) for(int a = b; a < c; ++a) #define eps 10e-8 const int MAX_ = 1010; const int N = 3000010; const int INF = 0x7fffffff; bool mp[MAX_][MAX_]; int l[MAX_], r[MAX_]; int h[MAX_]; int main(){ int n, T, m, ans; char c, str[10]; scanf("%d", &T); while(T--){ scanf("%d%d", &n, &m); REP(i, 0, n){ REP(j, 0, m){ //getchar(); //scanf("%c", &c);这样用c接收必错! WA了一次 scanf("%s", str); switch(str[0]){ case 'R': mp[i][j] = 1;//printf("%c ", 'R'); break; case 'F': mp[i][j] = 0;//printf("%c ", 'F'); break; } } //printf("\n"); } mst(h, 0); //printf("ok\n"); ans = -1; REP(i, 0, n){ REP(j, 0, m){ if(mp[i][j]) h[j] = 0; else h[j]++; } REP(x, 0, m){ l[x] = r[x] = x; } REP(x, 0, m){ while(l[x] > 0 && h[l[x] - 1] >= h[x]){ l[x] = l[l[x] - 1]; } } for(int x = m - 1; x > -1; --x){ while(r[x]+1 < m && h[r[x] + 1] >= h[x]){ r[x] = r[r[x] + 1];//printf("cao!\n"); } } REP(j, 0, m){ int tmp = h[j] * (r[j] - l[j] + 1); ans = max(ans, tmp); } } printf("%d\n", ans*3); } return 0; }