单调栈,故名思意,就是单调递增或者单调递减的栈。
单调栈,类似于单调队列,只不过它只是对一端进行操作。
具体单调栈的实现 :
1.维护从左往右递增栈可以得到左边第一个比a[i]小的元素位置L[i]。
2.维护从左往右递减栈可以得到左边第一个比a[i]大的元素位置L[i]。
3.维护从右往左递增栈可以得到右边第一个比a[i]小的元素位置R[i]。
4.维护从右往左递减栈可以得到右边第一个比a[i]大的元素位置R[i]。
emmmm,展示第一种情况的代码:
#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
stack<int> q;//定义一个栈q
int a[10],b[10];//数组a 是存储数字,b是存在a[i]左侧比其小的数目
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
while(q.size()) q.pop();//将栈清空
for(int i=0;i<n;i++)
{
while(q.size()&&a[q.top()]>=a[i]) q.pop();//单调栈核心代码
if(q.empty())
b[i]=0;
else
b[i]=q.top()+1;
q.push(i);
}
for(int i=0;i<n;i++)
cout<<b[i]<<" ";
return 0;
}
第二种的话只要改变a[q.top()]<=a[i]就行。
第三种情况的话 主要是修改顺序,注意输出的是按照正序。
#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
stack<int> q;//定义一个栈q
int a[10],b[10];//数组a 是存储数字,b是存在a[i]左侧比其小的数目
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
while(q.size()) q.pop();//将栈清空
for(int i=n-1;i>=0;i--)
{
while(q.size()&&a[q.top()]>=a[i]) q.pop();//单调栈核心代码
if(q.empty())
b[i]=0;
else
b[i]=q.top()+1;
q.push(i);
}
for(int i=0;i<n;i++)
cout<<b[i]<<" ";
return 0;
}
第四种情况就是修改三的符号。
最基本的例题,就是 hdu 1506 Largest Rectangle in a Histogramhttp://acm.hdu.edu.cn/showproblem.php?pid=1506
解法就是从左向右跑两次单调栈,第一次记录左边小于它的第一个位置,第二次记录右边第一次小于它的位置,所求面积就是矩形高度乘两次记录的距离差,max求最大即可。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<stack>
#include<queue>
#define maxn 100100
using namespace std;
stack<int >q;
int lt[maxn],rt[maxn];
long long int h[maxn],area[maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
for(int i=0;i<n;i++)
cin>>h[i];
while(q.size()) q.pop();
for(int i=0;i<n;i++)
{
while(q.size()&&h[q.top()]>=h[i]) q.pop();
if(q.empty())
lt[i]=0;
else
lt[i]=q.top()+1;
q.push(i);
}
while(q.size()) q.pop();
for(int i=n-1;i>=0;i--)
{
while(q.size()&&h[q.top()]>=h[i]) q.pop();
if(q.empty())
rt[i]=n;
else
rt[i]=q.top();
q.push(i);
}
long long int ans=0;
for(int i=0;i<n;i++)
area[i]=h[i]*(rt[i]-lt[i]);
for(int i=0;i<n;i++)
ans=max(ans,area[i]);
cout<<ans<<endl;
}
return 0;
}
也是刚接触单调栈这个东西,以后会慢慢补充的,这次就先这些。