zoukankan      html  css  js  c++  java
  • 悬线法学习笔记

    悬线法:一般求最大子矩形

    悬线法,悬线的定义,就是一条竖线,这条竖线要满足上端点在整个矩形上边界或者是一个障碍点。然后以这条悬线进行左右移动,直到移至障碍点或者是矩阵边界,进而确定这条悬线所在的极大矩阵。

    所以我们需要(Left[])数组存每个点能到达的最右位置,(Right[])数组存放每个点能到达的最左位置,(Up[])数组位置。

    设置好这些数组之后,我们开始遍历矩阵中的每个点,把每个点和上一个点的(Left)(Right)进行比较,分别取最大和最小,Up则是上一个点的Up+1,进而求出面积进行比较。

    经典例题:
    ZJOI2007 棋盘制作

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #define MAXN 2010
    using namespace std;
    int l[MAXN][MAXN],r[MAXN][MAXN],up[MAXN][MAXN],a[MAXN][MAXN];
    int n,m,ans1,ans2;
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%d",&a[i][j]),l[i][j]=j,r[i][j]=j,up[i][j]=1;
        for(int i=1;i<=n;i++)
            for(int j=2;j<=m;j++)
                if(a[i][j]==1-a[i][j-1])
                    l[i][j]=l[i][j-1];
        for(int i=1;i<=n;i++)
            for(int j=m-1;j>=1;j--)
                if(a[i][j]==1-a[i][j+1])
                    r[i][j]=r[i][j+1];
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(i>1&&a[i][j]==1-a[i-1][j])
                {
                    up[i][j]=up[i-1][j]+1;
                    l[i][j]=max(l[i-1][j],l[i][j]);
                    r[i][j]=min(r[i-1][j],r[i][j]);
                }
                int kuan=r[i][j]-l[i][j]+1;
                int square=min(kuan,up[i][j]);
                ans1=max(ans1,square*square);
                ans2=max(ans2,kuan*up[i][j]);
            }
        }
        printf("%d
    %d
    ",ans1,ans2);
        return 0;
    } 
    

    luogu 玉蟾宫

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #define MAXN 2010
    using namespace std;
    int l[MAXN][MAXN],r[MAXN][MAXN],up[MAXN][MAXN];
    char a[MAXN][MAXN];
    int n,m,ans1,ans2;
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                cin>>a[i][j],l[i][j]=j,r[i][j]=j,up[i][j]=1;
        for(int i=1;i<=n;i++)
            for(int j=2;j<=m;j++)
                if(a[i][j]=='F'&&a[i][j-1]=='F')
                    l[i][j]=l[i][j-1];
        for(int i=1;i<=n;i++)
            for(int j=m-1;j>=1;j--)
                if(a[i][j]=='F'&&a[i][j+1]=='F')
                    r[i][j]=r[i][j+1];
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(i>1&&a[i][j]=='F'&&a[i-1][j]=='F')
                {
                    up[i][j]=up[i-1][j]+1;
                    l[i][j]=max(l[i-1][j],l[i][j]);
                    r[i][j]=min(r[i-1][j],r[i][j]);
                }
                int kuan=r[i][j]-l[i][j]+1;
                ans2=max(ans2,kuan*up[i][j]);
            }
        }
        printf("%d
    ",3*ans2);
        return 0;
    } 
    
  • 相关阅读:
    Porter Stemming Algorithm
    Hook API to detect memory leak
    Are tuples more efficient than lists in Python?
    boost::intrusive_ptr VS boost::shared_ptr
    How Python GC deal with referencecycles?
    LINQ排序数组
    Sublime Text 2 (Version 2.0.1 build 2217) x64 破解注册方法
    GC in C# and Python
    Python中的else
    Managed C++ Destructor
  • 原文地址:https://www.cnblogs.com/fengxunling/p/9935945.html
Copyright © 2011-2022 走看看