zoukankan      html  css  js  c++  java
  • HDU 1505 & POJ 1964 City Game (递推+扫描法)

    题意:一个矩阵,有些格子是F,有些是R,要你找到最大的子矩阵使得矩阵内全是F

    思路:直接枚举每个子矩阵,显然复杂度是O(m^3 n^3),显然TLE。 

    我们可以使用扫描法:用up(i,j)表示格子(i,j)悬垂线(悬垂线就是指这个格子往上走遇到第一个R的格子之前的线段)的长度。left(i,j)表示悬垂线往左扫最左能移动到的位置(遇到R会停止),right(i,j)表示悬垂线往右扫最右能移动到的位置(遇到R会停止)。那么格子(i,j)可以对应一个这样的最大F矩形:以第i行作为底边,第i-up(i,j)+1行作为上底边,left(i,j)所在列为左边,right(i,j)所在列作为右边的矩形。

    那么最终答案就是每个格子对应的矩形中的最大值。

    up(i,j)可以用递推式:(1)若map[i][j]=='F',up(i,j)=up(i-1,j)+1 (2)若map[i][j]=='R',up(i,j)=0

    left(i,j)可以用递推式:(1)若map[i][j]=='F',left(i,j)=max{left(i-1,j),lo+1}  (lo是格子(i,j)左边最近的'R'的列)(2)若map[i][j]=='R',left(i,j)=0

    right(i,j)可以用递推式:(1)若map[i][j]=='F',right(i,j)=max{right(i-1,j),ro-1} (ro是格子(i,j)右边最近的'R'的列)(2)若map[i][j]=='R',right(i,j)=n


    注意:这个题目读入数据规模较大,用scanf会TLE。。。。getchar()才行。。。

    #include<cstdio>
    #include<iostream>
    #define MAXN 1005
    using namespace std;
    int T,n,m,righ[MAXN][MAXN],up[MAXN][MAXN],lef[MAXN][MAXN];
    char map[MAXN][MAXN];
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            int ans=0;
            scanf("%d%d",&m,&n); getchar();
            for(int i=0;i<m;++i)
                for(int j=0;j<n;++j)
                {
                    char ch=getchar();
                    while(ch!='F' && ch!='R') ch=getchar();//处理读入,注意用while,直到读入为F或者R为止
                    map[i][j]=ch;
                }
            for(int j=0;j<n;++j)
            for(int i=0;i<m;++i)
                if(map[i][j]=='R') up[i][j]=0;
                else up[i][j]=i? up[i-1][j]+1:1;//递推up(i,j)
    
            for(int i=0;i<m;++i)
            for(int j=0,lo=-1;j<n;++j)
                if(map[i][j]=='R') lo=j,lef[i][j]=0;
                else lef[i][j]=i? max(lo+1,lef[i-1][j]):lo+1;//递推left(i,j)
    
            for(int i=0;i<m;++i)
            for(int j=n-1,ro=n;j>=0;--j)
                if(map[i][j]=='R') ro=j,righ[i][j]=n;
                else righ[i][j]=i? min(ro-1,righ[i-1][j]):ro-1;//递推right(i,j)
    
            for(int i=0;i<m;++i)
                for(int j=0;j<n;++j)
                    if(map[i][j]=='F') ans=max(ans,(righ[i][j]-lef[i][j]+1)*up[i][j]);//计算答案取最大值
    
            printf("%d
    ",ans*3);
        }
        return 0;
    }
    


  • 相关阅读:
    人脸识别完整项目实战(1):目录大纲篇
    《分布式数据仓库最佳实践》学员答疑实录(2)
    知识图谱完整项目实战(附源码)(3)
    人脸识别完整项目实战(14):实时人脸特征点标定程序设计
    知识图谱完整项目实战(附源码)(2)
    sqlserver查询数据表中每个分类最新的一条记录
    WPF datagrid combobox 使用枚举
    中控考勤机开发-专业性门禁终端
    临时保存
    开源WPF控件库MaterialDesignInXAML推荐
  • 原文地址:https://www.cnblogs.com/bbsno1/p/3260509.html
Copyright © 2011-2022 走看看