周赛的题目,思想
011111
111111
000111
111111
111111
转换为
011111
122222
000333
111444
222555
然后按该位置的高度向两边扩展,当遇到小于该高度时,停止扩展,然后用右边的下标减左边的下标加一,
再乘以当前的高度即为所求,dp的实现是在计算第二个矩阵时用到的,只是简单的
h[i,j] = h[i-1,j]+1 (map[i][j]=='F')
#include <cstring>
#include <iostream>
#include <string>
using namespace std;
#define X 1005
string s;
int map[X][X],dp[X][X],l[X],r[X],m,n;
int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
int t;
cin>>t;
while(t--)
{
cin>>m>>n;
memset(map,0,sizeof(map));
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
cin>>s;
if(s=="F")
map[i][j] = 1;
}
}
for(int i=2;i<=m;i++)
for(int j=1;j<=n;j++)
if(map[i][j])
map[i][j] = map[i-1][j]+1;
int ans = 0;
for(int i=1;i<=n;i++)
if(map[1][i])
ans = 1;
for(int i=2;i<=m;i++)
{
for(int j=1;j<=n;j++) //向左扩展
{
l[j] = j;
while(l[j]>1&&map[i][l[j]-1]>=map[i][j])
l[j]--;
}
for(int j=1;j<=n;j++) //向右扩展
{
r[j] = j;
while(r[j]<n&&map[i][r[j]+1]>=map[i][j])
r[j]++;
}
for(int j=1;j<=n;j++) //更新当前的最大矩阵
if((r[j]-l[j]+1)*map[i][j]>ans)
ans = (r[j]-l[j]+1)*map[i][j];
}
cout<<ans*3<<endl; //3倍数输出
}
return 0;
}