最大全1子矩阵

http://blog.csdn.net/zhang20072844/article/details/12925581

给出1个M*N的矩阵M1,里面的元素只有0或1,找出M1的一个子矩阵M2,M2中的元素只有1,并且M2的面积是最大的。输出M2的面积。

Input

第1行:2个数m,n中间用空格分隔(2 <= m,n <= 100)
第2 - N + 1行:每行m个数,中间用空格分隔,均为0或1。

Output

输出最大全是1的子矩阵的面积。

Input 示例

3 3
1 1 0
1 1 1
0 1 1

Output 示例

4

题目分析:

这个题目N=100时可以根据最小子矩阵和求O(N^3),但是当N范围为1000时,就要求降一个数量级了。

这里我们可以一行一行的求。

比如第一行 1 1 0 1 1 1 0 1

那么我们求和b[]={1,1,0,1,1,1,0,1}

比如第二行为1 1 0 0 0 0 1 1

那么我们继续求和b[]={2,2,0,0,0,0,0,2}......

也就是说:

if(map[i][k])
     b[k] ++;

else
     b[k] = 0;

这样得到了了一个直方图,不知道大家有没有求过最大直方图面积的问题

就是不同高度的直方图,求这个直方图最大的矩形面积,如何去求?

比如直方图高度为 1 2 3 2,那么最大面积是?

当以第一个为基准的时候高度为1,后面的大于都可以组成矩形,所以面积为4.当以第二个为基准,那么只有后三个可以,面积为6.同理。。。。最大面积为6.

这里也是一样,当求得了第一行到当前行的高度后,可以求出目前的最大面积。

我们设立两个数组l[],r[]分别表示以b[j]为基准时候的左右边界,那么一b[j]为基准的面积就变成了b[j]*(r[j]-l[j]+1),然后枚举出最大的即可。

对于l[],r[],我们可以通过下面计算方法获得:

#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;

const int MAXN = 510;
int map[MAXN][MAXN];
int b[MAXN],l[MAXN],r[MAXN];

int M,N;

int main()
{
	while (cin >> M >> N)
	{
		int Max = 0;
		memset(map,0,sizeof(map));
		for (int i = 1; i <= M; ++ i)
		{
			for (int j = 1; j <= N; ++j)
			{
				cin >> map[i][j];
			}
		}

		for (int j = 0; j <= N+1; ++ j)
		{
			b[j] = 0;
		}
		for (int i = 1; i <= M; ++ i)//i表示以第I行作为底端
		{
			for (int k = 1; k <= N; ++ k)
			{
				if(map[i][k])
					b[k] ++;
				else
					b[k] = 0;
			}

			/*for (int j = 1; j <= N; ++ j)
			{//这种写法也可以我觉得
				int p = j;
				while (p>=1 && b[j] <= b[p--]);
				int q = j;
				while(q<=N && b[j] <= b[q ++]);
				if (b[j] && (b[j]*(q-p-1) > Max))
				{
					Max = b[j]*(q-p);
				}
			}*/
			for (int j = 1; j <= N; ++ j)
			{
				l[j] = j;
				while (l[j] - 1 >= 1 && b[j] <= b[l[j] - 1])
				{
					l[j] = l[l[j] - 1];//这么写的话更加快一点,直接写l[j]=l[j] - 1慢一点
				}
			}
			for (int j = N; j >= 1; -- j)
			{
				r[j] = j;
				while (b[j] <= b[r[j] + 1] && r[j] + 1 <= N)
				{
					r[j] = r[r[j] + 1];
				}
			}

			for (int j = 1; j <= N; ++ j)
			{
				if (b[j] && (b[j]*(r[j] - l[j]+1) > Max))
				{
					Max = b[j]*(r[j] - l[j]+1);
				}
			}
		}
		cout << Max << endl;
	}
	return 0;
}

  

时间: 2024-10-08 10:28:04

最大全1子矩阵的相关文章

Codevs 1159 最大全0子矩阵 悬线法!!!!

1159 最大全0子矩阵 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个0,1方阵中找出其中最大的全0子矩阵,所谓最大是指O的个数最多. 输入描述 Input Description 输入文件第一行为整数N,其中1<=N<=2000,为方阵的大小,紧接着N行每行均有N个0或1,相邻两数间严格用一个空格隔开. 输出描述 Output Description 输出文件仅一行包含一个整数表示要求的最大的全零子矩阵中零的个数.

1159 最大全0子矩阵

/*f(i,j)表示以(i,j)为右下角的最大全0子矩阵的边长若a[i][j]==1,f(i,j)=0否则:f(i,j)=min{ f(i-1,j),f(i,j-1),f(i-1,j-1) }+1 这样求得的是最大全0正方形子矩阵要求长方形矩阵,上述思路行不通假设以(i,j)为右下角的最大矩阵=12它可能是3*4.4*3.2*6.6*2.1*12.12*1按上述思路进行状态转移的话,取得最优值的方案不唯一时,所有的方案需要都记下,用于后续的状态转移. 在长方形全0子矩阵中,考察某个位置(i,j)

最大子段和||最大子矩阵和||最大全0子矩阵||最大全0子正方形

最大子段和(略) 定义一个最大值dp[i]表示以i结尾的最大子段和: 初始化: dp[0]=A[0]: dp[i]=max(dp[i-1]+A[i],A[i]) 即dp[i-1]+A[i]<0时 dp[i] = A[i]; 否则 dp[i]=dp[i-1]+A[i] 最大全0子矩阵 https://blog.csdn.net/Flere825/article/details/54605662 1159 最大全0子矩阵 /* #define N 2010 int a[N][N],ans,n; in

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])

Leetcode:Maximal Rectangle 最大全1子矩阵

Maximal Rectangle Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area. 解题分析: 联想到 最大矩形面积 这一题,可以在O(n)时间内求出 最大的矩形面积 如果我们把每一行看成x坐标,那高度就是从那一行开始往上数的1的个数. 利用 最大矩形面积 的方法,在O(n2)时间内就可以求出每一行形成的“柱状

[codevs1159]最大全0子矩阵(悬线法)

解题关键:悬线法模板题.注意此模板用到了滚动数组. #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> #define maxn 2002 using namespace std; typedef long long ll; int map[maxn][maxn],l[ma

面积最大的全1子矩阵--九度OJ 1497

题目描述: 在一个M * N的矩阵中,所有的元素只有0和1,从这个矩阵中找出一个面积最大的全1子矩阵,所谓最大是指元素1的个数最多. 输入: 输入可能包含多个测试样例.对于每个测试案例,输入的第一行是两个整数m.n(1<=m.n<=1000):代表将要输入的矩阵的大小.矩阵共有m行,每行有n个整数,分别是0或1,相邻两数之间严格用一个空格隔开. 输出: 对应每个测试案例,输出矩阵中面积最大的全1子矩阵的元素个数. 样例输入: 2 2 0 0 0 0 4 4 0 0 0 0 0 1 1 0 0

数据结构一:栈

[例子1]132 Pattern https://leetcode.com/problems/132-pattern/description/ Given a sequence of n integers a1, a2, ..., an, a 132 pattern is a subsequence ai, aj, ak such that i < j < k and ai < ak < aj. Design an algorithm that takes a list of n

POJ3494Largest Submatrix of All 1’s[单调栈]

Largest Submatrix of All 1’s Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 5883   Accepted: 2217 Case Time Limit: 2000MS Description Given a m-by-n (0,1)-matrix, of all its submatrices of all 1’s which is the largest? By largest we me