【bzoj3039】玉蟾宮
阿新 • • 發佈:2019-01-30
懸線法?
記錄up表示往上延伸的F的高度
然後變成每行求最大子矩形面積
單調遞增的棧,詳見poj2082
(回宿舍睡覺有空補更)
順帶Orz DQS學長手速五分鐘打完 + 提交 + 寫題解Orz
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stack>
using namespace std;
const int MAXN = 1000 + 5;
char map[MAXN][MAXN];
int up[MAXN][MAXN];
int n,m;
struct dot
{
int h,w;
};
void init()
{
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
up[i][j] = (up[i - 1][j] + 1) * (map[i][j] == 'F');
return;
}
void scanf(char &c)
{
c = getchar();
while(!isalpha(c))
c = getchar();
return ;
}
stack <dot> s;
int dpdpd()
{
int ans = 0;
for(int i = 1;i <= n;i ++)
{
for(int j = 1;j <= m;j ++)
{
int tmp = 0;
while(!s.empty() && s.top().h > up[i][j])
{
tmp += s.top().w;
ans = max(ans,s.top().h * tmp);
s.pop();
}
s.push((dot){up[i][j],tmp + 1 });
}
int tmp = 0;
while(!s.empty())
{
tmp += s.top().w;
ans = max(ans,s.top().h * tmp);
s.pop();
}
}
return ans;
}
int main()
{
scanf("%d %d",&n,&m);
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
scanf(map[i][j]);
init();
printf("%d\n",dpdpd() * 3);
return 0;
}