码迷,mamicode.com
首页 > 其他好文 > 详细

Luogu4147 玉蟾宫

时间:2018-11-02 23:59:27      阅读:282      评论:0      收藏:0      [点我收藏+]

标签:端点   turn   mes   math   get   预处理   ace   单调栈   line   

正解貌似是单调栈??然而我看起来这是个裸的最大子矩形啊qwq

于是用了DP

\(h(i,j)\)表示以\((i,j)\)为下端点的悬线的最长长度。

预处理\(l(i,j)\)\(r(i,j)\),它们分别表示点\((i,j)\)能扩展到的左边和右边的最近的障碍。

\(L(i,j)\)\(R(i,j)\)分别表示使悬线有此长度的左边最近的障碍和右边最近的障碍。

答案即为\(max(h(i,j)*(R(i,j)-L(i,j)+1)\)

CODE:

#include<iostream>
#include<cstdio>
using namespace std;
int n, m, f[1001][1001], ans, l[1001][1001], r[1001][1001];
int L[1001][1001], R[1001][1001], h[1001][1001];
char qwq;
int main(){
    scanf("%d%d", &n, &m);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++){
            do qwq=getchar();while(qwq!='R'&&qwq!='F');
            if(qwq=='F')
                f[i][j]=1;
        }
    for(int i=1; i<=n; i++){
        int t=0;
        for(int j=1; j<=m; j++)
            if(f[i][j]) l[i][j]=t;
            else L[i][j]=0, t=j;
        t=m+1;
        for(int j=m; j>0; j--)
            if(f[i][j]) r[i][j]=t;
            else R[i][j]=m+1, t=j;
    }
    for(int i=1; i<=m+1; i++)
        R[0][i]=m+1;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++){
            if(f[i][j]){
                h[i][j]=h[i-1][j]+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(ans, (R[i][j]-L[i][j]+1)*h[i][j]);
            }
        }
    printf("%d", 3*ans);
    return 0;
}

Luogu4147 玉蟾宫

标签:端点   turn   mes   math   get   预处理   ace   单调栈   line   

原文地址:https://www.cnblogs.com/pushinl/p/9898669.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!