描述 Description
有一天,小猫 rainbow 和 freda 来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。
这片土地被分成 N*M 个格子,每个格子里写着’R’或者’F’,R 代表这块土地被赐予了 rainbow,F 代表这块土地被赐予了 freda。
现在 freda 要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着’F’并且面积最大。
但是 rainbow 和 freda 的 OI 水平都弱爆了,找不出这块土地,而蓝兔也想看 freda 卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为 S,它们每人给你 S 两银子。
输入格式 InputFormat
第一行两个整数 N,M,表示矩形土地有 N 行 M 列。
接下来 N 行,每行 M 个用空格隔开的字符’F’或’R’,描述了矩形土地。
输出格式 OutputFormat
输出一个整数,表示你能得到多少银子,即 (3 * 最大’F’矩形土地面积) 的值。
样例输入 SampleInput
5 6
R F F F F F
F F F F F F
R R R F F F
F F F F F F
F F F F F F
样例输出 SampleOutput
45
求极大子矩阵。h[j]表示到当前行第 j 列有多少个连续的 F,len[j]表示当前行以 h[j]为高度的最大子矩阵的左端点,于是用单调栈可以优化。
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
using namespace std;
const int maxn=1005;
int i,j,t,n,m,l,r,k,z,y,x;
int a[maxn][maxn],h[maxn],len[maxn];
stack <int> s;
char ch[1];
int ans;
int main()
{
scanf("%d%d",&n,&m);
ans=0;
for (i=1;i<=n;i++)
{
while (!s.empty()) s.pop();
for (j=1;j<=m;j++)
{
len[j]=j;
scanf("%s",ch);
if (ch[0]=='R') h[j]=0;
else h[j]=h[j]+1;
while (!s.empty() && h[j]<h[s.top()])
{
ans=max(ans,(j-len[s.top()])*h[s.top()]);
len[j]=len[s.top()];
s.pop();
}
s.push(j);
}
while (!s.empty())
{
ans=max(ans,(m+1-len[s.top()])*h[s.top()]);
s.pop();
}
}
printf("%d\n",ans*3);
return 0;
}