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

bzoj3039 玉蟾宮

3039: 玉蟾宮

Time Limit: 2 Sec  Memory Limit: 128 MB
Submit: 606  Solved: 367
[Submit][Status][Discuss]

Description

有一天,小貓rainbow和freda來到了湘西張家界的天門山玉蟾宮,玉蟾宮宮主藍兔盛情地款待了它們,並賜予它們一片土地。
這片土地被分成N*M個格子,每個格子裡寫著'R'或者'F',R代表這塊土地被賜予了rainbow,F代表這塊土地被賜予了freda。
現在freda要在這裡賣萌。。。它要找一塊矩形土地,要求這片土地都標著'F'並且面積最大。
但是rainbow和freda的OI水平都弱爆了,找不出這塊土地,而藍兔也想看freda賣萌(她顯然是不會程式設計的……),所以它們決定,如果你找到的土地面積為S,它們每人給你S兩銀子。

Input

第一行兩個整數N,M,表示矩形土地有N行M列。
接下來N行,每行M個用空格隔開的字元'F'或'R',描述了矩形土地。

Output

輸出一個整數,表示你能得到多少銀子,即(3*最大'F'矩形土地面積)的值。

Sample Input

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

Sample Output

45

HINT



對於50%的資料,1<=N,M<=200

對於100%的資料,1<=N,M<=1000

Source


謹以此題獻給陪伴我童年的《虹貓藍兔七俠傳》。

將問題轉化為給定一個01矩陣,求出矩陣中由1組成的最大矩形的面積。

列舉矩形的底,求出每一列最高的1的高度,再用兩次單調棧分別維護每一列左端和右端第一個比它低的位置,相應算出包含此列的最大矩形面積,最後對所有結果取最大值。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define LL long long
using namespace std;
bool a[1005][1005];
int h[1005],s[1005],l[1005],r[1005],n,m,t,ans=0;
char ch;
int main()
{
	scanf("%d%d",&n,&m);
	F(i,1,n) F(j,1,m)
	{
		ch=getchar();
		while (ch!='F'&&ch!='R') ch=getchar();
		a[i][j]=(ch=='F');
	}
	memset(h,0,sizeof(h));
	memset(s,0,sizeof(s));
	F(i,1,n)
	{
		F(j,1,m)
		{
			if (a[i][j]) h[j]++;
			else h[j]=0;
		}
		t=0;
		s[0]=0;
		F(j,1,m)
		{
			while (t>0&&h[s[t]]>=h[j]) t--;
			l[j]=s[t]+1;
			s[++t]=j;
		}
		t=0;
		s[0]=m+1;
		D(j,m,1)
		{
			while (t>0&&h[s[t]]>=h[j]) t--;
			r[j]=s[t]-1;
			s[++t]=j;
		}
		F(j,1,m) ans=max(ans,h[j]*(r[j]-l[j]+1));
	}
	printf("%d\n",ans*3);
}