护林员盖房子

一、题目描述

总时间限制: 

1000ms

 

内存限制: 

65536kB

描述

在一片保护林中,护林员想要盖一座房子来居住,但他不能砍伐任何树木。 
现在请你帮他计算:保护林中所能用来盖房子的矩形空地的最大面积。

输入

保护林用一个二维矩阵来表示,长宽都不超过20(即<=20)。 
第一行是两个正整数m,n,表示矩阵有m行n列。 
然后是m行,每行n个整数,用1代表树木,用0表示空地。

输出

一个正整数,表示保护林中能用来盖房子的最大矩形空地面积。

样例输入

4 5
0 1 0 1 1
0 1 0 0 1
0 0 0 0 0
0 1 1 0 1

样例输出

5

提示

子矩阵边长可以为1,也就是说: 
0 0 0 0 0 
依然是一个可以盖房子的子矩阵。

二、解题思路

类似最大子段和算法,采用动规对每一行进行计算得出第i行第j个元素的最大相接空格数b[i][j](包括元素本身且列<j的与元素相连最大空格数)。得到之后可以对每一个元素进行遍历计算,即以当前元素为右下角空格为计算,分以下两种:

1、若当前元素为1(即不为空格),则continue。

2、当前元素为0(即为空格),则设当前矩形最大长度为b[i][j],宽为1。然后遍历往上找(即列数每次减一找上一行),若找到的当前元素为1,则break,否则长取min(当前长, b[i][j‘]),宽加1。并且当前找到的矩阵大小为:长*宽,则及时更新全局最大值。

三、代码

#include <iostream>
using namespace std;
int main (){
	int m, n;
	cin>>m>>n;
	int a[m+1][n+1];
	int b[m+1][n+1];
	for(int i = 1; i <= m; i++)  // 输入矩阵 
		for(int j = 1; j <= n; j++)
			cin>>a[i][j];
			
	for(int i = 1; i <= m; i++){  // 计算每一行的每一个元素,值为包括它自己的及之前的相连最大空格数 
		if(a[i][1] == 0) b[i][1] = 1;
		else b[i][1] = 0;
		for(int j = 2; j <= n; j++){
			if(a[i][j] == 1) b[i][j] = 0;
			else b[i][j] = b[i][j-1] + 1;
		}
	}
	int Max = 0;
	for(int i=1; i<=m; i++){
		for(int j=1; j<=n; j++){    
			if(a[i][j] == 1) continue;
			else{
				int length = b[i][j];
				int width = 1;
				for(int t = i-1; t>=1; t--){
					if(a[t][j] == 1)
						break;
					else{
						width++;
						length = min(length, b[t][j]);
						Max = max(Max, length*width);
					}
				}
			}
		}
	}
	cout<<Max<<endl;
	
	return 0;
} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章