code vs 最大全0子矩阵

1159 最大全0子矩阵

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 黄金 Gold
题解
 查看运行结果

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

输入描述 Input Description

输入文件第一行为整数N,其中1<=N<=2000,为方阵的大小,紧接着N行每行均有N个0或1,相邻两数间严格用一个空格隔开。

输出描述 Output Description

输出文件仅一行包含一个整数表示要求的最大的全零子矩阵中零的个数。

样例输入 Sample Input

5
0 1 0 1 0
0 0 0 0 0
0 0 0 0 1
1 0 0 0 0
0 1 0 0 0

样例输出 Sample Output

9


悬线法求最大全0子矩阵

r,h,l都为滚动数组,l表示向左最远可以扩展的距离,r表示向右最远可以扩展的距离,h表示向上最远可以扩展的距离

具体思路参见浅谈有极大化思想解决最大子矩阵问题

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int m,n,i,j,r[2003],l[2003],h[2003],a[2003][2003],ans,la,ra;
int main()
{
	scanf("%d",&n);
	m=n;
	for (i=1;i<=n;i++)
	 for (j=1;j<=m;j++)
	  scanf("%d",&a[i][j]);
	for (i=1;i<=m;i++)
	 h[i]=0,l[i]=1,r[i]=m;
	for (i=1;i<=n;i++)
	 {
	 	la=0; ra=m+1;//la表示左边第一个障碍点的位置,ra表示右边第一个障碍点的位置
	 	for (j=1;j<=m;j++)
	 	 if (a[i][j])//如果当前点为1,那么他就是一条悬线的起点
	 	  h[j]=0,la=j,l[j]=1;
	 	 else
	 	  h[j]++,l[j]=max(l[j],la+1);//h[j]++表示的是在上一行的基础上高度+1
	 	for (j=m;j>0;j--)
	 	 if (a[i][j])
	 	  r[j]=m,ra=j;
	 	 else
	 	  r[j]=min(ra-1,r[j]),ans=max(ans,(r[j]-l[j]+1)*h[j]);
	 }
	printf("%d",ans);
} 


你可能感兴趣的:(code vs 最大全0子矩阵)