城市游戏
题目描述 Description
鲍勃是一个战略游戏编程专家。在他的新城市建设游戏游戏环境如下:一个城市建立了地区,有街道、树木,工厂和建筑物。在该地区仍然有一些空间是空置的。他游戏的战略任务是赢得尽可能多的房租钱从这些免费空间。
赢得房租钱你必须建造建筑,只能是长方形的,长和宽。鲍勃正试图找到一种方法来建造尽可能最大的在每个区域。
但他遇到一些问题——他是不允许破坏已经存在的建筑、树木、工厂和街道建筑。
每个地区都有其宽度和长度。平等广场的区域划分为网格单元。租金支付您正在构建的每个单元站是3美元。
你的任务是帮助鲍勃解决这个问题。整个城市分为K地区。
每一个长方形的区域是有自己不同的网格大小与长度宽度M和N。现有的占领,单位是标明符号R ,空置单位标记符号F。输入描述 Input Description
输入一行包含区域描述。
定义了一个描述在以下方式:第一行包含两个数,长度M < = 1000和宽度N < = 1000,由一个空格分开
下M行包含N个符号,标志着保留或自由网格单元,由一个空格分开。使用的符号是:
R -保留单位
F -免费的单位
输出描述 Output Description
为每个数据集在输入打印在单独的行中,在标准输出,整数表示装配获得的利润最大的建筑区域编码的数据集。
样例输入 Sample Input5 6
R F F F F F
F F F F F FR R R F F F
F F F F F FF F F F F F
样例输出 Sample Output
45
[解题思路]
可以把R替换成0,F替换成1,即看成求最大子矩阵的问题,而这里将用另一种方法求解。即在一个0-1矩阵里面找出最大一个全1子矩阵。用二维数组来存放矩阵,从matrix[1][1]到matrix[i][j]遍历,由于,找一个最大的全1矩阵,即找出全1矩阵的最大面积,面积可以用h[j]*(r[j]-l[j]+1)表示,其中h[j]为最大高度,r[j]为最右的位置,l[j]为最左位置,所以(r[j]-l[j]+1)为最大宽度。
[代码实现]
/*最大全1子矩阵问题*/
#include<iostream>
using namespace std;
int matrix[1005][1005];
char cmatrix[1005][1005];
int h[1005];
int r[1005];
int l[1005];
int n,m,ans;
void GetMax(int n,int m)
{
int i,j,k;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(matrix[i][j]==1)
h[j]++;
else
h[j]=0;
}
h[0]=h[m+1]=-1;
for(j=1;j<=m;j++) //l[i]表示h[i]左边最远的一个h值不小于h[i]的位置
{ //即l[i]到i的所有h值均>=h[i],r[i]同理
k=j;
while(h[j]<=h[k-1]) k=l[k-1];
l[j]=k;
}
for(j=m;j>=1;j--) //r[i]表示h[i]右边最远的一个h值不小于h[i]的位置
{
k=j;
while(h[j]<=h[k+1]) k=r[k+1];
r[j]=k;
}
for(j=1;j<=m;j++)
{
if(ans<h[j]*(r[j]-l[j]+1)) ans=h[j]*(r[j]-l[j]+1);
}
}
}
void Input()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>cmatrix[i][j];
}
}
}
void TransForm()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(cmatrix[i][j] == 'F')
matrix[i][j]=1;
}
int main(int argc,char *argv[])
{
Input();
TransForm();
GetMax(n,m);
cout<<ans*3<<endl;
return 0;
}