题目链接:传送门
分析:题意大概就是要求一个由F和R构成的矩阵中,单单由F构成的最大矩阵
思路:运用到dp思想,但第一次做还是比较难想到,用一个dp数组记录高度,再用两个数组分别来表示某个点向左和向右延伸的最大宽度,最后再计算每块的面积就OK了
AC代码:
#include<iostream>
#include<cstring>
using namespace std;
int dp[1005][1005]; //记录高度
int main(){
int k;
cin>>k;
while(k--){
int n,m;
cin>>n>>m;
int l[1005],r[1005]; //记录一个点向左和向右延伸的最大宽度
memset(dp,0,sizeof(dp));
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
char c;
cin>>c;
if(c=='F') dp[i][j]=dp[i-1][j]+1; //如果该点为F就是上一层的高度再加1
}
long long max=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
l[j]=r[j]=j;
dp[i][0]=-1;
dp[i][m+1]=-1;
for(int j=1;j<=m;j++) //若左边点的高度大于该点,则该点的左边界向左延伸
while(dp[i][l[j]-1]>=dp[i][l[j]]) l[j]=l[j-1];
for(int j=m;j>=1;j--)
while(dp[i][r[j]+1]>=dp[i][r[j]]) r[j]=r[j+1];
for(int j=1;j<=m;j++) //遍历每一点计算下面积
if(dp[i][j]*(r[j]-l[j]+1)>max) max=dp[i][j]*(r[j]-l[j]+1);
}
cout<<max*3<<endl;
}
}