首页 > 代码库 > CODEVS1159 最大全0子矩阵

CODEVS1159 最大全0子矩阵

题目描述 Description

在一个0,1方阵中找出其中最大的全0子矩阵,所谓最大是指O的个数最多。

思路:这个题最朴素的n^6的算法,超时美美的。。。然后想优化,从一个点向上方、左方、右方扩展,首先更新这个点向上能有多少个0h0,然后找左右h比h0大的作为左右边界,然后计算这个矩形的面积,最后输出最大值。。。这种构造的美丽算法,真心。。。

比较: 最大全0子正方形:f[i][j](以i,j为右下角的最大正方形的边长)=min(f[i-1][j],f[i][j-1],f[i-1][j-1]),这里用了正方形的特性,所以和矩形的求法不同。
这属于dp中的重要分支,最大子图形问题,详细的讲解可以参考下面的网址。。。真心丧病。。。 
http://www.docin.com/p-46970779.html 

code:

#include<iostream>

#include<cstdio>

using namespace std;

int li[2001]={0},ri[2001]={0},hi[2001]={0},a[2001][2001]={0};

int main()

{

int n,i,j,ans=0;

scanf("%d",&n);

for (i=1;i<=n;++i)

  for (j=1;j<=n;++j)

    scanf("%d",&a[i][j]);

for (i=1;i<=n;++i)

{

for (j=1;j<=n;++j)

{

  if (a[i][j]==0) ++hi[j];

  else hi[j]=0;

  li[j]=ri[j]=j;

    }

    for (j=2;j<=n;++j)

      if (a[i][j]==0)

        while (hi[li[j]-1]>=hi[j])

          li[j]=li[li[j]-1];

for (j=n-1;j>=1;--j)

  if (a[i][j]==0)

        while (hi[ri[j]+1]>=hi[j])

          ri[j]=ri[ri[j]+1];

    for (j=1;j<=n;++j)

      if (a[i][j]==0)

        ans=max(ans,(ri[j]-li[j]+1)*hi[j]);

}

cout<<ans<<endl;

}

CODEVS1159 最大全0子矩阵