hi.玉蟾宫(最大子矩形问题 / 悬线法)

P4147 玉蟾宫

题目背景

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

题目描述

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

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

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

输入格式

第一行两个整数 N N N M M M,表示矩形土地有 N N N M M M 列。

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

输出格式

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

输入输出样例 #1

输入 #1

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

输出 #1

45

说明/提示

hi.玉蟾宫(最大子矩形问题 / 悬线法)_第1张图片

对于 50 % 50\% 50% 的数据, 1 ≤ N , M ≤ 200 1 \leq N, M \leq 200 1N,M200
对于 100 % 100\% 100% 的数据, 1 ≤ N , M ≤ 1000 1 \leq N, M \leq 1000 1N,M1000

代码内容

#include  
using namespace std;  

typedef long long ll;
const ll N=1e3+10;  
ll a[N][N],h[N][N];
ll l[N][N],r[N][N],L[N][N],R[N][N];  

int main()
{ 
    ll n,m;
    cin>>n>>m;

    for(ll i=1;i<=n;i++)
        for(ll j=1;j<=m;j++)
        {
            char c;
            cin>>c;
            if(c=='F') a[i][j]=1;
        } 
        
    for(ll i=1;i<=n;i++)
    {
        ll t=0;
        for(ll j=1;j<=m;j++)//枚举左边的障碍
        {
            if(a[i][j]) l[i][j]=t;
            else L[i][j]=0,t=j;
        }
        t=m+1;
        for(ll j=m;j>=1;j--)//枚举右边的障碍
        {
            if(a[i][j]) r[i][j]=t;  
            else R[i][j]=m+1,t=j;
        }
    }

    for(ll i=1;i<=m+1;i++) R[0][i]=m+1;

    ll ans=0;
    for(ll i=1;i<=n;i++)
        for(ll j=1;j<=m;j++)
        {
            if(a[i][j])
            {
                h[i][j]=h[i-1][j]+1;//如果这个点是合法的,对应的悬线长度应当比它下面的点对应的悬线长大1  
                L[i][j]=max(l[i][j]+1,L[i-1][j]);
                R[i][j]=min(r[i][j]-1,R[i-1][j]);
                ans=max((R[i][j]-L[i][j]+1)*h[i][j],ans); //求出最大的面积
            }       
        }

    cout<<3*ans<<endl;
    return 0;
} 

你可能感兴趣的:(算法,c++)