☆[BZOJ3039 ]玉蟾宫 (单调栈)
题目背景
有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。
题目描述
这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda。
现在freda要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着'F'并且面积最大。
但是rainbow和freda的OI水平都弱爆了,找不出这块土地,而蓝兔也想看freda卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为S,它们每人给你S两银子。
输入格式
第一行两个整数N,M,表示矩形土地有N行M列。
接下来N行,每行M个用空格隔开的字符'F'或'R',描述了矩形土地。
输出格式
输出一个整数,表示你能得到多少银子,即(3*最大'F'矩形土地面积)的值。
输入输出样例
输入 #1
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
输出 #1
45
说明/提示
对于50%的数据,1<=N,M<=200
对于100%的数据,1<=N,M<=1000
一开始单纯地以为是暴搜,(其实是没看清求“矩形” 大雾x)
看清题目以后不由得想起了最大矩形面积那道题,感觉可以用差不多的思路来写。
第一个做法比较好理解,后面慢慢写一下单调栈,再学习一下悬线orz
#include<bits/stdc++.h> const int N = 1010; using namespace std; #define For(i,l,r) for(register int i=l; i<=r; i++) int n,m,ans,t; int a[N][N],h[N][N], l[N][N],r[N][N]; char c; int main() { cin >> n >> m; For(i,1,n) For(j,1,m){ cin >> c; if(c == 'F')a[i][j] = 1; else a[i][j] = 0; } For(i, 1, m) r[0][i] = m+1; //矩形土地 For(i, 1, n){ For(j, 1, m) if(a[i][j]) h[i][j] = h[i-1][j] + 1; //高 else h[i][j] = 0; t = 0; For(j, 1, m) if(a[i][j]) l[i][j] = max(l[i-1][j],t); //左 else l[i][j] = 0, t = j; t = m+1; for(int j=m;j;j--) if(a[i][j]) r[i][j] = min(r[i-1][j], t); //右 else r[i][j] = m + 1, t = j; For(j, 1, m) ans=max(ans, (r[i][j] - l[i][j] - 1) * h[i][j]); } cout << 3*ans; return 0; }
满堂花醉三千客,一剑霜寒十四州