单调栈

单调栈简介

单调栈是一种基于栈的数据结构,类似于优先队列,顾名思义内部数据保持单调的数据结构,即单调递增或单调递减。

这里拿栈内数据严格单调递减来举例子。
单调栈同样是先进后出,首先读入一个数据,有两种情况:

一是如果栈为空,则直接把数据存入栈尾。
二是这个数据和栈尾作比较,如果大于等于栈尾,则把栈尾数据出栈,接着比较拿输入数据与新栈尾作比价,直到小于栈尾,则入栈。

可以用数组或者STL(链表)实现。

代码如下:
因为STL用起来更像易读,刚学想试下 ,所以就用STL写了,但是平时做题为了方便还是会用数组实现,其实就是插入排序的一部分

#include<stack>
using namespace std;	
stack<int>sta;
void fun(int num[],int len)		//要插入栈的数据
{
	int t;
	int i;
	for(i=0;i<len;i++){
		t=num[i];
		while(!sta.empty()&&t>=sta.top()){	//判断
			sta.pop();
			//弹出栈顶后往往还要对这些数据作操作
			//具体试情况而定,这里就不写了 
		}
		sta.push(t);						//入栈
	}
}

简单还是简单,就是不知道啥时候用orz 所以拿一个裸题来找下感觉。

1.剪头发问题http://poj.org/problem?id=3250
题意:有n个身高输入,代表从左到右的每个人身高,每个人都向右看,但是只能看到比他身高矮(小于)的人的发型,并且视线会被中间更高的人挡住。

解法:可以从左到右读这组数据,构建一个栈内数据严格单调递减的单调栈,每有一个新元素入栈,意味着栈内原本的元素数量的人可以看到这个新元素。唯一要注意数据可能有爆int所以要用长整型。
所以AC代码:

#include<cstdio>
#define max_n 80005
const int INF=1e9+5;
using namespace std;
int h[max_n],ans[max_n];
int main()
{
	long long int ans;
	int end;
	int n,t;
	scanf("%d",&n);
	h[0]=INF;				
	//一个技巧是把栈里第一个元素设置成INF,单调递增则是设置成-INF
	ans=end=0;					//end代表栈顶的下标
	while(n--){
		scanf("%d",&t);
		while(t>=h[end]){		//判断
			end--;
		}
		ans+=end;				//加上之前栈内有多少个元素
		h[++end]=t;				//入栈
	}
	printf("%lld\n",ans);
	return 0;
}

因为每个元素有一次入栈和出栈所以复杂度为O(2n)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值