護林員蓋房子

一、題目描述

總時間限制: 

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;
} 

 

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