CodeForces - 320D A - Psychos in a Line(棧)
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
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;
}