洛谷 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#include #include #define N 1005#define inf 0x7fffffffusing 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 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;}