Codeforces 319B. Psychos in a Line单调栈
Posted tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 319B. Psychos in a Line单调栈相关的知识,希望对你有一定的参考价值。
题目链接:
http://codeforces.com/problemset/problem/319/B
题意:
一串数列,每一个值如果大于相邻右一位的值的话,那么就可以把右边这个值“吃掉”(右一位消失,原来的值不变),问需要吃多少次才能到达无法再吃的状态。
思路:
利用栈。遍历一遍数组,处理每个值的时候,如果栈顶的元素小于该值,那么将其弹出,知道栈顶元素大于该值或者栈为空,栈内的每个元素记录下一个属性:他是在第几次被“吃掉”,进栈的新元素的被吃次数就是它弹出去的元素中的属性的最大值+1,如果没有弹任何值则为1;如果栈空,则值为0;
保持整个队列递减
策略如下
如果一个数进去没有弹出数,则这个数肯定是第一场就被消掉的
如果一个数进去弹出了一些数,则该数被吃掉的场次等于它弹走的所有数中最大的被吃掉的场次序号+1,因为,这个数肯定是在它弹掉的数之后被吃掉的(它被弹完后的队列中最后面一个数吃掉)
如果一个数进去弹出了所有的数,则这个数被吃掉的场次为0
当然,一开始是要找到从第一个开始的单调子串中的最后一个数作为这个队列的第一个数,并且场次为0
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define MS(a) memset(a,0,sizeof(a)) #define MP make_pair #define PB push_back const int INF = 0x3f3f3f3f; const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; inline ll read(){ ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } ////////////////////////////////////////////////////////////////////////// const int maxn = 1e5+10; int n,a[maxn]; struct node{ int x,y; }que[maxn]; int main(){ cin >> n; for(int i=1; i<=n; i++) a[i] = read(); int i=2; while(a[i]>a[i-1]) i++; int tail = 0, ans = 0, mx=0; que[tail].x = a[i-1], que[tail++].y = 0; for( ; i<=n; i++){ if(a[i] < que[tail-1].x){ que[tail].x = a[i], que[tail++].y = 1; ans = max(ans,que[tail-1].y); continue; } mx = 0; while(tail>0 && a[i]>que[tail-1].x) mx=max(mx,que[tail-1].y),tail--; que[tail].x = a[i]; if(tail==0) que[tail++].y=0; else que[tail++].y=mx+1; ans = max(ans,que[tail-1].y); } cout << ans << endl; return 0; }
以上是关于Codeforces 319B. Psychos in a Line单调栈的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces319 C. Kalila and Dimna in the Logging Industry(dp,斜率优化)
codeforces 576c// Points on Plane// Codeforces Round #319(Div. 1)
Codeforces Round #319 (Div. 2) E - Points on Plane