洛谷 P4147 玉蟾宫

洛谷 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;
}
上一篇:「BZOJ3039」玉蟾宫


下一篇:978. 最长湍流子数组