CodeForces - 320D A - Psychos in a Line(栈)

探讨了一个涉及心理战游戏的算法问题,通过使用栈数据结构,有效地解决了最少轮次内消除所有攻击关系的计算难题。文章详细介绍了算法思路与实现过程,包括如何从前向后遍历数组并计算每一步所需的最小步数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

There are n psychos standing in a line. Each psycho is assigned a unique integer from 1 to n. At each step every psycho who has an id greater than the psycho to his right (if exists) kills his right neighbor in the line. Note that a psycho might kill and get killed at the same step.

You're given the initial arrangement of the psychos in the line. Calculate how many steps are needed to the moment of time such, that nobody kills his neighbor after that moment. Look notes to understand the statement more precise.

Input

The first line of input contains integer n denoting the number of psychos, (1 ≤ n ≤ 105). In the second line there will be a list of n space separated distinct integers each in range 1 to n, inclusive — ids of the psychos in the line from left to right.

Output

Print the number of steps, so that the line remains the same afterward.

Examples

input

10
10 9 7 8 6 5 3 4 2 1

output

2

input

6
1 2 3 4 5 6

output

0

题意:给出1到n的一个序列a[1].a[2]...a[n],每一轮,如果a[i]>a[i+1],则称a[i]杀掉s[i+1],则可以从数列中去掉a[i+1],并且,一个数可以同时将右边一个数杀掉并且被左边数杀掉,问:最少经过几轮,不会存在杀掉关系?

思路:一开始其实并没有想到用栈,想的是搜索??

大体的思想是,从后往前遍历数组,ans数组记录杀到能杀的人需要的步数

ac代码:

#include<iostream>
#include<stack>
using namespace std;
int a[100005],ans[100005];
int main()
{
	int n,i;
	stack<int> s;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
		scanf("%d",&a[i]);

	for(i=n;i>=1;i--)
	{
		if(s.empty()) {
			s.push(a[i]);
			ans[i]=0;
			continue;
		}
		
		if(a[i]<s.top())
		{
			s.push(a[i]);
			ans[a[i]]=0;
		}
		else if(a[i]>s.top())
		{
			int temp=max(1,ans[s.top()]);//这里和下面好好想想,当前a[i]的ans和它之前的ans的关系 
			s.pop();
			while(!s.empty()&&a[i]>s.top())
			{
				temp=max(temp+1,ans[s.top()]);//其实就是找它前面的人杀人所需最多的步数 ,但是至少也得每次加1 
				s.pop();  //杀完一个就弹出,也避免了上面的+1重复 
			}
			ans[a[i]]=temp;
			s.push(a[i]);
		}
	
	}
	int maxx=0;
	for(i=1;i<=n;i++)
	maxx=max(maxx,ans[i]);
	cout<<maxx<<endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值