有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。
这片土地被分成N*M个格子,每个格子里写着’R’或者’F’,R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda。
现在freda要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着’F’并且面积最大。
但是rainbow和freda的OI水平都弱爆了,找不出这块土地,而蓝兔也想看freda卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为S,它们将给你3*S两银子。
输入格式
第一行包括两个整数N,M,表示矩形土地有N行M列。
接下来N行,每行M个用空格隔开的字符’F’或’R’,描述了矩形土地。
每行末尾没有多余空格。
输出格式
输出一个整数,表示你能得到多少银子,即(3*最大’F’矩形土地面积)的值。
数据范围
1≤N,M≤1000
输入样例:
5 6
R F F F F F
F F F F F F
R R R F F F
F F F F F F
F F F F F F
输出样例:
45
这题第一眼看起来可以用暴力,但是数据量大时,TLE就在所难免。
这时我们来分析题。
1.要组成最大的矩阵。且只由F构成。
2.组成矩阵,每个F要连续。
所以感觉是不是像最大直方图的面积问题呢。
这个时候我们可以,先统计从第一行到每一行,连续的矩阵个数。记住时连续且包含该行也要是F。
所以可以得出下一行的数量h[i][j] = h[i-1][j] + 1, 如果当前行不是F,则h[i][j] = 0;
然后问题变成枚举每一行,求出最大直方图问题。
代码:
#include <iostream> #include <algorithm> #include <cstring> using namespace std; const int N = 1010; int h[N][N];//存储F的数量 char g[N][N]; int s[N], w[N];//s为栈,w时宽度 int n, m; int work(int a[]) { int p = 0; a[m+1] = 0; int ans = 0; for(int i = 1; i <= m+1; ++ i) { if(a[i] > s[p]) s[++p] = a[i], w[p] = 1; else { int width = 0; while(s[p] > a[i]){ width += w[p]; ans = max(ans, width*s[p]); p--; } s[++p] = a[i], w[p] = width + 1; } } return ans; } int main() { cin >> n >> m; for(int i = 1; i <= n; ++ i) for(int j = 1; j <= m; ++ j) { char c; cin >> c; g[i][j] = c; if(c == 'F') h[i][j] = h[i-1][j] + 1; else h[i][j] = 0; } int ans = 0; for(int i = 1; i <= n; ++ i) ans = max(ans, work(h[i]));//枚举每一行 cout << ans * 3 << endl; return 0; }