zoukankan      html  css  js  c++  java
  • 扫描线法求最大子矩阵

    问题描述:

    给定一个N*M的矩阵,其中有一些格子是空地,其他是障碍。

    找出一个全部由空地组成的面积/周长最大的子矩阵。


    朴素算法:

    枚举左上角的坐标O(mn)和右下角的坐标O(mn),判断是否全为空地O(mn),时间复杂度为O(m3*n3)。


    扫描线法:

    把点(i,j)向上所有连续的空格看做一条悬线。矩阵中的每个点都向上对应了一条悬线。


    ①用h[i,j]表示点(i,j)对应的悬线长度。

    当(i,j)为障碍时,h[i,j]=0;当(i,j)为空格时,h[i,j]=h[i-1,j]+1。


    ②用left[i,j]表示点(i,j)对应的悬线的左边界。

    当(i,j)为障碍时,left[i,j]=左边界;当(i,j)为空格时,left[i,j]=max( left[i-1,j], lo+1 ),lo为格子(i,j)左边最近障碍的列编号。


    ③用right[i,t]表示点(i,j)对应的悬线的右边界。

    当(i,j)为障碍时,right[i,j]=右边界; 当(i,j)为空格时,right[i,j]=min( right[i+1,j], ro-1 ),ro为格子(i,j)右边最近障碍的列编号。


    从上到下扫描,对每一行,从左到右计算left[i,j]维护lo;从右到左计算right[i,j]维护ro并更新答案。

    在实际实现中,降维节约空间,用h[j],left[j],right[j] 表示当前扫描行的信息。


    模板:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn=1111;
    
    int mat[maxn][maxn];
    int n,m;
    
    //返回矩形的最大面积,障碍物代号为c
    int cat(int c)
    {
        int h[maxn],l[maxn],r[maxn];
        int lo,ro;
        int ans=0;
        for (int j=1;j<=m;j++)
        {
            h[j]=0;
            l[j]=1;
            r[j]=m;
        }
        for (int i=1;i<=n;i++)
        {
            lo=0;ro=m+1;
            for (int j=1;j<=m;j++)
            {
                if (mat[i][j]==c){ h[j]=0;l[j]=1;lo=j; }
                else
                {
                    h[j]++;
                    l[j]=max(l[j],lo+1);
                }
            }
            for (int j=m;j>=1;j--)
            {
                if (mat[i][j]==c){ r[j]=m;ro=j; }
                else
                {
                    r[j]=min(r[j],ro-1);
                    ans=max(ans,h[j]*(r[j]-l[j]+1));
                }
            }
        }
        return ans;
    }
    


    题目:

    UVa 1330 - City Game 最大子矩阵

    hdu 4328 Cut the cake 最大子矩阵



  • 相关阅读:
    Redis21:客户端与服务器端的通信与redis管道
    Redis20:keys、scan、bigkeys、查看key的存储方式
    Redis19:限流
    Redis18:分布式锁
    Redis17:cluster集群
    Redis16:两种redis集群解决方案:codis和cluster
    Android : 获取声卡信息的测试代码
    Android : 基于alsa库的音乐播放
    Android system :灯光系统_HAL_lights
    Android system :led_class驱动
  • 原文地址:https://www.cnblogs.com/cyendra/p/3226298.html
Copyright © 2011-2022 走看看