1. 程式人生 > >【bzoj3039】玉蟾宮

【bzoj3039】玉蟾宮

懸線法?

記錄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; }