bzoj3039 玉蟾宫

单调栈 专栏收录该内容
5 篇文章 0 订阅

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);
}


  • 0
    点赞
  • 1
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 程序猿惹谁了 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值