博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
单调栈学习笔记
阅读量:5952 次
发布时间:2019-06-19

本文共 2956 字,大约阅读时间需要 9 分钟。

 线性结构——单调栈

①定义:栈内的元素,按照某种方式排序(单调递增或单调递减)如果新入栈的元素破坏了单调性,就弹出栈内元素,直到满足单调性
②优点:可以很方便地求出某个数左边或者右边第一个比他大或者小的元素,总时间复杂度为O(n)
③如何维护单调栈(以递增为例)
进栈操作:每次入栈前先检验栈顶元素和进栈元素x的大小,如果小于x,就让x
     直接入栈。如果栈顶元素大于等于x,那么出栈,直到栈空或者栈顶元素小于x。
     
【例1】最大矩形面积(poj2559)

1 #include
2 using namespace std; 3 const int N=100002; 4 int h[N],n; 5 int line[N],L[N],R[N],top=0; 6 int main(){ 7 scanf("%d",&n); 8 for(int i=1;i<=n;i++) 9 scanf("%d",&h[i]);10 for(int i=1;i<=n;i++){11 while(top&&h[line[top]]>=h[i]) top--;12 L[i]=top?line[top]+1:1;13 line[++top]=i;14 }15 top=0;16 for(int i=n;i>=1;i--){17 while(top&&h[line[top]]>=h[i]) top--;18 R[i]=top?line[top]-1:n;19 line[++top]=i;20 }21 int maxn=0;22 for(int i=1;i<=n;i++){23 int ans=h[i]*(R[i]-L[i]+1);24 maxn=max(maxn,ans);25 }26 cout<
<
代码戳这里

 

【例2】玉蟾宫(luogu P4147)

讲一讲我自己的思路(其实是同学教的)吧,似乎不是很好的解?但我感觉比较好理解……
首先把输入的字符矩阵转移为数字,即s[i][j]代表第i行第j列这一格上面连续的F的个数(如果这一格是S的话就是0),所以预处理之后就把样例变成了这样:
0 1 1 1 1 1
1 2 2 2 2 2
0 0 0 3 3 3
1 1 1 4 4 4
2 2 2 5 5 5
代码实现:

for(int i=1;i<=n;i++)    for(int j=1;j<=m;j++){        char ch;        cin>>ch;        if(ch=='F') s[i][j]=s[i-1][j]+1;    }

然后就有点类似于上面那道题了,每一行分开分析,找到每一个位置可以向左右扩展的最长的长度,这是矩形的长,而组成的矩形的宽就是这一格中对应的数字,所以向左右两边扩展的条件就是要扩展的那一格中的数字一定大于等于当前扫描到的这一格的数字。(似乎没太讲清楚啊QAQ)每一行处理出一个可以组成的矩形的最大面积,用一个maxn取最大值就可以找到最后的答案了。

代码实现:

for(int i=1;i<=n;i++){    int ans=0;//用于记录当前这一行的矩形最大面积    for(int j=1;j<=m;j++){        int l=j,r=j;//l代表左边能扩展到的最远位置,r代表右边能扩展到的最远位置        while(l>=1&&s[i][l]>=s[i][j]) l--;        l++;        while(r<=m&&s[i][r]>=s[i][j]) r++;        r--;        ans=max(ans,s[i][j]*(r-l+1));//当前这一行的最大矩形面积    }    maxn=max(ans,maxn);//每一行的最大矩形面积比较取最大值}

以下完整代码(没开O2的时候T了两个点QAQ)

1 // luogu-judger-enable-o2 2 #include
3 #include
4 #include
5 using namespace std; 6 const int N=1002; 7 int K,n,m; 8 int s[N][N]; 9 int maxn=0;10 int max(int x,int y){11 return x>y?x:y;12 }13 int main(){14 //scanf("%d",&K);15 //while(K--){
16 memset(s,0,sizeof(s));17 scanf("%d%d",&n,&m);18 for(int i=1;i<=n;i++)19 for(int j=1;j<=m;j++){20 char ch;21 cin>>ch;22 if(ch=='F') s[i][j]=s[i-1][j]+1;23 }24 for(int i=1;i<=n;i++){25 int ans=0;//用于记录当前这一行的矩形最大面积26 for(int j=1;j<=m;j++){27 int l=j,r=j;//l代表左边能扩展到的最远位置,r代表右边能扩展到的最远位置28 while(l>=1&&s[i][l]>=s[i][j]) l--;29 l++;30 while(r<=m&&s[i][r]>=s[i][j]) r++;31 r--;32 ans=max(ans,s[i][j]*(r-l+1));//当前这一行的最大矩形面积33 }34 maxn=max(ans,maxn);//每一行的最大矩形面积比较取最大值35 }36 printf("%d\n",maxn*3);//最后别忘了乘337 //}38 return 0;39 }
代码戳这里

 

转载于:https://www.cnblogs.com/THWZF/p/10161208.html

你可能感兴趣的文章
React 组件通信之 React context
查看>>
Centos下基于Hadoop安装Spark(分布式)
查看>>
3D地图的定时高亮和点击事件(基于echarts)
查看>>
mysql开启binlog
查看>>
设置Eclipse编码方式
查看>>
分布式系统唯一ID生成方案汇总【转】
查看>>
并查集hdu1232
查看>>
Mysql 监视工具
查看>>
从前后端分离到GraphQL,携程如何用Node实现?\n
查看>>
Linux Namespace系列(09):利用Namespace创建一个简单可用的容器
查看>>
nginc+memcache
查看>>
Numpy中的random模块中的seed方法的作用
查看>>
关于jsb中js与c++的相互调用
查看>>
POJ-2251 Dungeon Master
查看>>
tortoisesvn的安装
查看>>
URAL 1353 Milliard Vasya's Function DP
查看>>
速读《构建之法:现代软件工程》提问
查看>>
Android onclicklistener中使用外部类变量时为什么需要final修饰【转】
查看>>
django中聚合aggregate和annotate GROUP BY的使用方法
查看>>
TFS简介
查看>>