• 机房测试8:question(求最大1矩阵:悬线法 or 二分)


    题目:

     分析:

    法一:二分套二分

    如果是二分最大矩阵的长,再二分最大矩阵的宽,明显是错的:

    1 1 1 0

    0 1 1 0

    像这样一组数据,如果宽二分到3,那么就不再会考虑宽为2的矩阵了,而最优矩阵是2*2=4

    如果再先二分矩阵的宽,再二分矩阵的长,可以水掉更多的点,但还是没有正确性。

    只有矩形的面积才是满足单调性的,如果一个面积大的矩形存在,面积小的也一定存在,二分完面积之后,再二分宽,然后枚举每一个点n^2 check

    复杂度:O(n*m*logn*log(n*m))(有点悬)

    法二:悬线法

    对于一个点,我们想利用它来扩展出对于包括它的,最大的一个矩形。初始化三个值:l[i][j],r[i][j],up[i][j]

    分别表示:某个点向左、向右、向上最多能扩展的位置。

    为什么能保证矩阵合法?

    l[i][j]=max(l[i-1][j],l[i][j]);
    r[i][j]=min(r[i-1][j],r[i][j]);
    up[i][j]=up[i-1][j]+1;

    代码里面的这三句保证了矩阵一定是合法的。

    为什么能保证每一个对答案有贡献的矩阵能够找齐?

    001100

    111111

    如果对于第二行的3、4个点,它们找到的矩阵是2*2=4的,而1*6=6的矩阵可以由1、2、5、6找到。

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1005
    #define ri register int
    int a[N][N],l[N][N],r[N][N],up[N][N],n,m;
    int read()//ll
    {
        int x=0,fl=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') fl=-1; ch=getchar(); }
        while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=getchar();
        return x*fl;
    }
    int main()
    {
        freopen("question.in","r",stdin);
        freopen("question.out","w",stdout);
        int fl=0,ans;
        n=read(), m=read();
        for(ri i=1;i<=n;++i) 
         for(ri j=1;j<=m;++j)
          a[i][j]=read(),l[i][j]=j,r[i][j]=j,up[i][j]=1,fl|=a[i][j];
        for(ri i=1;i<=n;++i)
         for(ri j=2;j<=m;++j)
          if(a[i][j-1] && a[i][j]) 
           l[i][j]=l[i][j-1];
        for(ri i=1;i<=n;++i)
         for(ri j=m-1;j>=1;--j)
          if(a[i][j+1] && a[i][j])
           r[i][j]=r[i][j+1];
        for(ri i=1;i<=n;++i)
         for(ri j=1;j<=m;++j){
             if(a[i][j] && a[i-1][j]){
                 l[i][j]=max(l[i-1][j],l[i][j]);
                 r[i][j]=min(r[i-1][j],r[i][j]);
                 up[i][j]=up[i-1][j]+1;
            }
            ans=max( ans,up[i][j]*(r[i][j]-l[i][j]+1) );
        }
        printf("%d
    ",fl ? ans : 0);
    }
    /*
    7 8 
    1 1 0 0 1 0 1 0 
    0 1 1 1 1 1 0 1 
    0 0 0 0 0 0 1 1 
    0 0 1 1 0 1 1 0 
    1 1 1 1 1 0 0 1 
    0 1 1 1 1 1 1 0 
    0 0 0 1 0 0 0 1 
    
    
    8 1 
    0 
    0 
    1 
    0 
    0 
    0 
    1 
    1 
    
    */
    View Code
  • 相关阅读:
    Android 聊天表情输入、表情翻页带效果、下拉刷新聊天记录
    android启动界面
    ubuntu 关于sublime text3的一些应用
    [LeetCode]Valid Sudoku解题记录
    在 Mac OS X 10.10 安装 pyenv 的一个小坑
    java调用百度地图API依据地理位置中文获取经纬度
    debug openStack
    error recoder,error debug for openStack kilo
    SDN,NFV
    openStack kilo 手动Manual部署随笔记录
  • 原文地址:https://www.cnblogs.com/mowanying/p/11635529.html
Copyright © 2020-2023  润新知