LA 3029 City Game

LA 3029

求最大子矩阵问题,主要考虑枚举方法,直接枚举肯定是不行的,因为一个大矩阵的子矩阵个数是指数级的,因此应该考虑先进行枚举前的扫描工作。

使用left,right,up数组分别记录从i,j位置可以向左,右,上扩展的最大距离,那么最终只需要枚举每一个方块即可使用(right-left)*up

 

 

#include <iostream>
#include <cstring>
#define M(a) memset(a,0,sizeof(a))
using namespace std;
const int maxn=1e3+10;
char mat[maxn][maxn];
int up[maxn][maxn],lef[maxn][maxn],righ[maxn][maxn];
int m,n;

void Init()
{
    cin>>m>>n;
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
            cin>>mat[i][j];
    }
    M(up);
    M(lef);
    M(righ);
}

void Work()
{
    for(int i=1;i<=m;i++)
    {
        int l=0;
        for(int j=1;j<=n;j++)
        {
            up[i][j]=up[i-1][j]+1;
            if(mat[i][j]=='R')
            {
                up[i][j]=0;
                lef[i][j]=0;//这里设它为零,避免对后面的取值产生影响
                l=j;        //同时也无需担心会对ans取值产生影响,因为up(i,j)为零
            }
            else
            {
                if(i==1) lef[i][j]=l+1;
                else
                lef[i][j]=max(lef[i-1][j],l+1);
            }
        }
        int r=n+1;
        for(int j=n;j>=1;j--)
        {
            if(mat[i][j]=='R')
            {
               r=j;
               righ[i][j]=n+1;
            }
            else
            {
                if(i==1) righ[i][j]=r-1;
                else
                righ[i][j]=min(righ[i-1][j],r-1);
            }
        }
    }
}

void Print()
{
    int ans=0;
    for(int i=1;i<=m;i++)
    for(int j=1;j<=n;j++)
    {
       ans=max(ans,3*(righ[i][j]-lef[i][j]+1)*up[i][j]);
    }
    cout<<ans<<endl;
}

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        Init();
        Work();
        Print();
    }
    return 0;
}
View Code

 

posted @ 2015-10-28 19:46  江南何采莲  阅读(130)  评论(0编辑  收藏  举报