目录
一、题目描述
总时间限制:
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;
}