• 悬线法求最大子矩阵


    [戳我](https://www.luogu.com.cn/record/38515341)

    思路

    悬线法,顾名思义,就是我们从一个点开始,想左上方出两根线,构成一个矩阵,然后遍历所有的点,取一个最大值就可以了。所以我们之前可以预处理出一个点可以到达的最上面的点和最下面的点,然后枚举宽度,对宽度也就是行上面的点的l和r值取min就可以得到这个矩阵的长和宽了。顺便给出此题的单调栈做法,求取宽度的方法类似,只是枚举长度的时候用了一个单调栈去维护

    代码实现

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iostream>
    #include<stack>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define MT(x,i) memset(x,i,sizeof(x) )
    #define rev(i,start,end) for (int i=start;i<end;i++)
    #define inf 0x3f3f3f3f
    #define mp(x,y) make_pair(x,y)
    #define lowbit(x) (x&-x)
    #define MOD 1000000007
    #define exp 1e-8
    #define N 1000005 
    #define fi first 
    #define se second
    #define pb push_back
    typedef long long ll;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    typedef vector <int> VI;
    typedef pair<int ,int> PII;
    typedef pair<int ,PII> PIII;
    ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;};
    void check_max (int &a,int b) { a=max (a,b);}
    void check_min (int &a,int b) { a=min (a,b);}
    inline int read() {
        char ch=getchar(); int x=0, f=1;
        while(ch<'0'||ch>'9') {
            if(ch=='-') f=-1;
            ch=getchar();
        } while('0'<=ch&&ch<='9') {
            x=x*10+ch-'0';
            ch=getchar();
        } return x*f;
    }
    const int maxn=3e3+10;
    int ans,n,m;
    int maze[maxn][maxn];
    int l[maxn][maxn],r[maxn][maxn];
    int up[maxn][maxn];
    inline int readc () {
        char c=getchar ();
        while (c!='R'&&c!='F') c=getchar ();
        if (c=='F') return 1;
        return 0;
    }
    
    int main () {
       scanf ("%d%d",&n,&m);
       ans=0;
       rep (i,1,n) 
        rep (j,1,m) maze[i][j]=readc (),up[i][j]=1,l[i][j]=r[i][j]=j;
       
       rep (i,1,n) 
        rep (j,2,m) if (maze[i][j]==1&&maze[i][j-1]==1) l[i][j]=l[i][j-1];
       rep (i,1,n) 
        per (j,m-1,1) if (maze[i][j]==1&&maze[i][j+1]==1) r[i][j]=r[i][j+1];
       
       rep (i,1,n) 
        rep (j,1,m) {
            if (i>1&&maze[i][j]==1&&maze[i-1][j]==1) {
                check_min (r[i][j],r[i-1][j]);
                check_max (l[i][j],l[i-1][j]);
                up[i][j]=up[i-1][j]+1;
            }
            check_max (ans,up[i][j]*(r[i][j]-l[i][j]+1));
        }
        printf ("%d
    ",3*ans);
        return 0;
    }
    
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define MT(x,i) memset(x,i,sizeof(x) )
    #define rev(i,start,end) for (int i=start;i<end;i++)
    #define inf 0x3f3f3f3f
    #define mp(x,y) make_pair(x,y)
    #define lowbit(x) (x&-x)
    #define MOD 1000000007
    #define exp 1e-8
    #define N 1000005 
    #define fi first 
    #define se second
    #define pb push_back
    typedef long long ll;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    typedef vector <int> VI;
    typedef pair<int ,int> PII;
    typedef pair<int ,PII> PIII;
    ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;};
    void check_max (int &a,int b) { a=max (a,b);}
    void check_min (int &a,int b) { a=min (a,b);}
    inline int read() {
        char ch=getchar(); int x=0, f=1;
        while(ch<'0'||ch>'9') {
            if(ch=='-') f=-1;
            ch=getchar();
        } while('0'<=ch&&ch<='9') {
            x=x*10+ch-'0';
            ch=getchar();
        } return x*f;
    }
    const int maxn=3e3+10;
    int t;
    struct node {
        int height,length;
    }st[maxn];
    int pos[maxn][maxn];
    int ans=0,temp=0;
    int n,m;
    
    inline int getc () {
        char c;
        c=getchar ();
        while (c!='R'&&c!='F') c=getchar ();
        if (c=='F') return 1;
        return 0;
    }
    
    void solve (int num) {
        int top=1,k;
        temp=0;
        st[1].height=pos[num][1];
        st[1].length=1;
        rep (i,2,m) {
            k=0;
            while (st[top].height>=pos[num][i]&&top>0) {
                k+=st[top].length;
                temp=max (temp,st[top--].height*k);
            }
            st[++top].height=pos[num][i];
            st[top].length=k+1;
        }
        k=0;
        while (top>0) {
            k+=st[top].length;
            temp=max (temp,st[top--].height*k);
        }
        ans=max (ans,temp);
    }
    
    int main () {
        MT (pos,0);
        scanf ("%d%d",&n,&m);
        rep (i,1,n) 
         rep (j,1,m) {
            int x=getc ();
            if (x==1) pos[i][j]=pos[i-1][j]+1;        
         }
        rep (i,1,n) solve (i);
        ans*=3;
        printf ("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    input不可编辑
    span width无效
    react配置rem解决移动端适配问题
    iframe 根据内容自适应高度-终极解决方案
    页面导入样式时,使用link和@import有什么区别?
    怎么让Chrome支持小于12px 的文字?
    React Hook 父子组件相互调用方法
    CSS3实现毛玻璃效果
    React阻止组件渲染
    JSX 中内联条件渲染的方法
  • 原文地址:https://www.cnblogs.com/hhlya/p/13687343.html
Copyright © 2020-2023  润新知