《算法竞赛进阶指南》城市游戏

有一天,小猫 rainbow 和 freda 来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。

这片土地被分成 N×MN×M 个格子,每个格子里写着 R 或者 FR 代表这块土地被赐予了 rainbow,F 代表这块土地被赐予了 freda。

现在 freda 要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着 F 并且面积最大。

但是 rainbow 和 freda 的 OI 水平都弱爆了,找不出这块土地,而蓝兔也想看 freda 卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为 SS,它们将给你 3×S3×S 两银子。

输入格式

第一行包括两个整数 N,MN,M,表示矩形土地有 NN 行 MM 列。

接下来 NN 行,每行 MM 个用空格隔开的字符 F 或 R,描述了矩形土地。

每行末尾没有多余空格。

输出格式

输出一个整数,表示你能得到多少银子,即(3×3×最大 F 矩形土地面积)的值。

数据范围

1≤N,M≤10001≤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

解题思路:
利用递推的方式枚举每一个构造出:https://blog.csdn.net/qq_61935738/article/details/125583420这个图
然后直接套这个题的题解 

#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1010;

int n, m;
int stk[N];
int h[N][N];
int l[N], r[N];

void get_bound(int a[], int last[])
{
    int top = 0;
    a[0] = -1;
    for (int i = 1; i <= m; i ++ )
    {
        while (a[stk[top]] >= a[i]) top -- ;
        last[i] = stk[top];
        stk[++ top] = i;
    }
}

int work(int h[])
{
    get_bound(h, l);
    reverse(h + 1, h + m + 1);
    get_bound(h, r);
    
    int res = 0;
    for (int i = 1, j = m; i <= m; i ++ , j -- )
    {
        res = max(res, h[i] * (m - r[i] - l[j]));
    }
    
    return res;
}

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m; j ++ )
        {
            char c;
            cin >> c;
            if (c == 'F') h[i][j] = h[i - 1][j] + 1;//构造直方图
            else h[i][j] = 0;
        }
    
    int res = 0;
    for (int i = 1; i <= n; i ++ ) res = max(res, work(h[i]));//枚举每一行的直方图
    
    cout << res * 3 << endl;
    
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啥也不会hh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值