码迷,mamicode.com
首页 > 其他好文 > 详细

[tyvj]P1939玉蟾宫[单调栈]

时间:2017-10-30 11:25:28      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:row   std   int   include   dash   void   work   top   并且   

[tyvj]P1939

玉蟾宫

——!x^n+y^n=z^n

背景

有一天,小猫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

输出

45


 

考虑下面这种情况,就是所有宽为1的矩形的底在同一直线上,我们可以考虑用栈来维护,为什么呢?

技术分享

注意到对于每一个小矩形,他对答案的贡献为向左延伸和向右延伸的最大值,如果后面加进一个低一点的元素,那这个就没啥用了,何不如直接删掉?

用单调栈,一个记录栈顶元素,另一个记录在当前索引应删除的元素。

那只需预处理出s[i][j]第i行,第j列,能向右延长的最大值,每次枚举底部,那我们只需要每次加入元素并更新答案即可。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 inline int read();
 6 int Max(int x,int y){return x>y?x:y;}
 7 namespace lys{
 8     const int N = 1e3 + 7 ;
 9     int s[N][N],s1[N],s2[N],a[N][N];
10     int n,m,ans,top,del;
11     void work(int row){
12         top=0;
13         for(int i=1;i<=n+1;i++){
14             del=i;
15             while(top&&s1[top]>=s[i][row]){
16                 ans=Max(ans,s1[top]*(i-s2[top]));
17                 del=s2[top--];
18             }
19             s1[++top]=s[i][row];s2[top]=del;
20         }
21     }
22     int main(){
23         int i,j;
24         char c;
25         n=read(); m=read();
26         for(i=1;i<=n;i++)
27             for(j=1;j<=m;j++){
28                 c=getchar();
29                 while(c!=F&&c!=R) c=getchar();
30                 if(c==F) a[i][j]=1;    
31             }
32         for(i=1;i<=n;i++)
33             for(j=m;j>=1;j--)
34                 s[i][j]=a[i][j]?s[i][j+1]+1:0;
35         for(i=1;i<=m;i++) work(i);
36         printf("%d\n",3*ans);
37         return 0;
38     }
39 }
40 int main(){
41     lys::main();
42     return 0;
43 }
44 inline int read(){
45     int kk=0,ff=1;
46     char c=getchar();
47     while(c<0||c>9){
48         if(c==-) ff=-1;
49         c=getchar();
50     }
51     while(c>=0&&c<=9) kk=kk*10+c-0,c=getchar();
52     return kk*ff;
53 }

 

[tyvj]P1939玉蟾宫[单调栈]

标签:row   std   int   include   dash   void   work   top   并且   

原文地址:http://www.cnblogs.com/Liisa/p/7752994.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!