玉蟾宫

题目链接:https://www.luogu.com.cn/record/214917040

题意:

给定一个矩阵,求F矩阵的最大面积

思路:

题目要求用O(N x M)的复杂度求解

因此思路是类似求解接水问题,利用单调栈优化复杂度

具体来说:设f[i][j]:从第i行第j列向上最大的F矩阵高度,对于每一行可以利用dp:f[i][j]=g[i][j]=='F'?(f[i-1][j]+1:0)

那么对于这一行的每一列来说,要求的是 以它的高度为标准 最多可以往左 + 往右扩展多少距离

显然当往左/往右的列高度比标准小,扩展操作停止

因此问题转化为一个数组上求每一个数左边第一个比它小的数,和右边第一个比它小的数

即可使用单调栈

int ans;
int right_min[maxn];
int left_min[maxn];
stack<int>stk;
stack<int>stk2;

void solve(){
    int n,m;cin>>n>>m;
    rep(i,1,n){
        rep(j,1,m)f[i][j]=1;
    }

    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            char op;cin>>op;
            if(op=='F')f[i][j]+=f[i-1][j];
            else f[i][j]=0;
        }
    }
  
 
    for(int i=1;i<=n;i++){

        for(int j=1;j<=m;j++){
            
            while(stk.size()&&f[i][stk.top()]>f[i][j]){
                right_min[stk.top()]=j;
                stk.pop();
            }
            stk.push(j);
        }

        while(stk.size()){
            right_min[stk.top()]=m+1;
            stk.pop();
        }
        
        for(int j=m;j>=1;j--){

            while(stk2.size()&&f[i][stk2.top()]>f[i][j]){
                left_min[stk2.top()]=j;
                stk2.pop();
            }
            stk2.push(j);
        }

        while(stk2.size()){
            left_min[stk2.top()]=0;
            stk2.pop();
        }


        for(int j=1;j<=m;j++){
            ans=max(ans,f[i][j]*(right_min[j]-left_min[j]-1));
        }


    }


    cout<<3*ans<<endl;
}
posted @ 2025-04-24 18:55  Marinaco  阅读(16)  评论(0)    收藏  举报
//雪花飘落效果