洛谷 P4147 玉蟾宫
Description
-
这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda。
现在freda要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着'F'并且面积最大。
但是rainbow和freda的OI水平都弱爆了,找不出这块土地,而蓝兔也想看freda卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为S,它们每人给你S两银子。
Input
-
第一行两个整数N,M,表示矩形土地有N行M列。
接下来N行,每行M个用空格隔开的字符'F'或'R',描述了矩形土地。
Output
- 输出一个整数,表示你能得到多少银子,即(3*最大'F'矩形土地面积)的值。
Sample Input
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
Sample Output
45
Data Size
-
对于50%的数据,1<=N,M<=200
对于100%的数据,1<=N,M<=1000
题解:
- 单调栈。
- emmmm…….每次加入一行,一行一行地添加。每添加一行就做一遍“直方图中的最大矩形”。
- 复杂度是O(nm),欸刚好。
#include <iostream>
#include <cstdio>
#include <stack>
#define N 1005
#define inf 0x7fffffff
using namespace std;
struct Node {int val, pos;};
int n, m, ans = -inf;
int h[N], l[N], r[N];
int a[N][N];
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
char c[3]; scanf("%s", c);
if(c[0] == 'R') a[i][j] = 1;
else a[i][j] = 2;
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
if(a[i][j] == 1) h[j] = 0;
else h[j]++;
stack<Node> stk1, stk2;
stk1.push((Node){-inf, 0});
for(int j = 1; j <= m; j++)
{
while(stk1.top().val >= h[j]) stk1.pop();
l[j] = stk1.top().pos + 1;
stk1.push((Node){h[j], j});
}
stk2.push((Node){-inf, m + 1});
for(int j = m; j >= 1; j--)
{
while(stk2.top().val >= h[j]) stk2.pop();
r[j] = stk2.top().pos - 1;
stk2.push((Node){h[j], j});
}
for(int j = 1; j <= m; j++)
{
int tmp = h[j] * (r[j] - l[j] + 1);
ans = max(ans, tmp);
}
}
cout << 3 * ans;
return 0;
}