Psychos in a Line

Psychos in a Line

TimeLimit:1000MS  MemoryLimit:256MB

64-bit integer IO format:%I64d

Problem Description

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.

SampleInput 1

1010 9 7 8 6 5 3 4 2 1

SampleOutput 1

2

SampleInput 2

61 2 3 4 5 6

SampleOutput 2

0

Note

In the first sample line of the psychos transforms as follows: [10 9 7 8 6 5 3 4 2 1]  →  [10 8 4]  →  [10]. So, there are two steps.

题意:

  一堆神经病站成一列, 神经病拥有的 id 如果 大于 右边的神经病的 id, 就可以砍死对方。

需要注意的是, 5 4 3 变成 5, 只需一步, 即是说符合条件的话, 可以同时砍右边的神经病。

一开始连题意都不懂, 真是糟糕。

后来经过学长的题解, 题意才渐渐明白。可是题解的理解, 还是有点懵逼。真是惭愧。

所以, 就放弃治疗, 自己去探索。

举例子吧。

给 15 个神经病人。id 如下

        15  9  5  10  7  11  14  6  2  3  12  1  8  13  4

干掉变化如下:

  第一步:  15 10 11  14  3  12 8 13

  第二步:  15 11 14  12 13

  第三步:    15 14 13

  第四步:  15

到这里, 其实也是一脸懵逼。

就想在原来的数列上去表上各个 id 是在第几步被干掉的。 然后再去模拟 id 被干掉的步数即可。其实我觉得也算是模拟题吧。

干掉步数:  + 1  1   2   1   3    4   1  1  2   3  1  2    4  1

原id:    15  9  5  10  7  11  14  6  2  3  12  1  8  13  4

用 单调栈去做。若是比之前的 id 大, 则 在之前的 id 的 次数 上 + 1 与之 取 最大。 需要注意的是, 当 栈 为 0 ,该 id  次数需要初始化为 0, 若是比栈中的 id 小, 若是第一次比 前一个数小, 则 次数 初始化为 1, 否则 之前 复制栈中 id 的次数。

code:

#include <cstdio>
using namespace std;
const int all = (1e5)+5;
int maxnum[ all ], con[ all ], stac[ all ], t, cnt;
bool isfirst;
#define Max( i, j )  (i) > (j) ? (i) : (j);
int main(void)
{
    scanf( "%d", &t );
    for( int i=0; i < t; ++ i ){
        scanf( "%d", con+i );
    }

    isfirst = true;
    for( int i=0, j=0; i < t; ++ i, ++ j ){
        if( j && con[i] > stac[j-1] ){
            while( j && con[i] >stac[j-1] ){
                -- j;
                maxnum[ con[i] ] = Max( maxnum[ con[i] ], maxnum[ stac[j] ] + 1 );
                stac[ j ] = con[i];
            }
            isfirst = true;
        }
        else{
            if( isfirst ){
                maxnum[ con[i] ] = 1;
            }
            else{
                maxnum[ con[i] ] = maxnum[ stac[j-1] ];
            }
            stac[j] = con[i];
        }

        if( !j ){
            maxnum[ stac[j] ] = 0;
        }
    }

    cnt = 0;
    for( int i=0; i < all; ++ i ){
        cnt = cnt > maxnum[i] ? cnt : maxnum[i];
    }
    printf( "%d\n", cnt );

    return 0;
}

时间: 2024-10-06 00:30:28

Psychos in a Line的相关文章

Codeforces Round #189 (Div. 1) B. Psychos in a Line 单调队列

B. Psychos in a Line Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/319/B Description 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 h

Codeforces 319B. Psychos in a Line【单调栈】

题目链接: http://codeforces.com/problemset/problem/319/B 题意: 一串数列,每一个值如果大于相邻右一位的值的话,那么就可以把右边这个值"吃掉"(右一位消失,原来的值不变),问需要吃多少次才能到达无法再吃的状态. 思路: 利用栈.遍历一遍数组,处理每个值的时候,如果栈顶的元素小于该值,那么将其弹出,知道栈顶元素大于该值或者栈为空,栈内的每个元素记录下一个属性:他是在第几次被"吃掉",进栈的新元素的被吃次数就是它弹出去的元

cf319b Psychos in a Line(单调队列 贪心)

#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> using namespace std; #define MAXN 100000+10 int n,st[MAXN],cnt,a[MAXN],kill[MAXN]={0},f[MAXN]={0}; int main() {

CF 319B Psychos in a Line 【单调队列】

给出一排神经病的编号1-n的某个排列 给出规则 一步能同时消除该数右边连续的小于该数的数 问几步能消到最后状态 在纸上试了试,觉得这个问题很有点像lis,但是苦于方法 突然看了一眼tags 单调队列 oh it is 可以把这些数字一个一个的加入单调队列中 同时记录每个数字被吃掉的场次 保持整个队列递减 策略如下 如果一个数进去没有弹出数,则这个数肯定是第一场就被消掉的 如果一个数进去弹出了一些数,则该数被吃掉的场次等于它弹走的所有数中最大的被吃掉的场次序号+1 因为,这个数肯定是在它弹掉的数之

Codeforces 319B. Psychos in a Line【栈】

题目大意: 一串数列,每一个值如果大于相邻右一位的值的话,那么就可以把右边这个值"吃掉"(右一位消失,原来的值不变),问需要吃多少次才能到达无法再吃的状态. 做法: 利用栈.遍历一遍数组,处理每个值的时候,如果栈顶的元素小于该值,那么将其弹出,知道栈顶元素大于该值或者栈为空,栈内的每个元素记录下一个属性:他是在第几次被"吃掉",进栈的新元素的被吃次数就是它弹出去的元素中的属性的最大值+1,如果没有弹任何值则为1:如果栈空,则值为0: 代码: #include <

R:incomplete final line found by readTableHeader on

报错: In read.table("abc.txt", header = T) :  incomplete final line found by readTableHeader on 'abc.txt' 解决方法: 在数据文件abc.txt最后一行加上回车即可解决.

windows git安装后更换the line ending conversions

Is there a file or menu that will let me change the settings on how to deal with line endings? There are 3 options: Checkout Windows-style, commit Unix-style line endings Git will convert LF to CRLF when checking out text files. When committing text

hdu 5691 Sitting in Line

传送门 Sitting in Line Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 293    Accepted Submission(s): 143 Problem Description 度度熊是他同时代中最伟大的数学家,一切数字都要听命于他.现在,又到了度度熊和他的数字仆人们玩排排坐游戏的时候了.游戏的规则十分简单,参与

error: bad top line in state file /var/lib/logrotate.status 解决方法

发现日志切割并没有按计划执行,后来手动强制执行时,发现如下报错: [[email protected] logrotate.d]# logrotate -f httpd error: bad top line in state file /var/lib/logrotate.status [[email protected] logrotate.d]# 解决访求: 删除/var/lib/logrotate.status 这个文件即可解决. 解决后,最好再运行一下logrotate -f /etc