一、題目描述
總時間限制:
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;
}