#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
int n;
int h[300010],u[300010],d[300010],a[300010];
int main(){
scanf("%d",&n);
memset(a,inf,sizeof(a));
for(int i=1;i<=n;i++)
{
scanf("%d",&h[i]);
}
int tu=1,td=1;///栈内元素个数(栈顶的下标)
u[1]=1,d[1]=1;///栈内存的是每个数在h中的位置,不是具体的数
a[1]=0;///到达i需要a【i】步
for(int i=2;i<=n;i++)
{
while(tu>0&&h[i]<h[u[tu]])///递增序列不为空,且当前元素小于栈顶元素
{
a[i]=min(a[i],a[u[tu]]+1);///从栈顶可以一步跨到当前位置(向上拱起的弧)
tu--;///找到>=h【i】的最小的数
}
a[i]=min(a[i],a[u[tu]]+1);///若栈空则就是a[i](a[0]无限大,或h[i]==h[u[tu]],则可由u[tu]跳到i (4 5 5 4中的两个4)
while(td>0&&h[i]>h[d[td]])///递减序列
{
a[i]=min(a[i],a[d[td]]+1);
td--;
}
a[i]=min(a[i],a[d[td]]+1);
if(h[u[tu]]==h[i])tu--;///严格单调
if(h[d[td]]==h[i])td--;
d[++td]=i;
u[++tu]=i;
}
printf("%d\n",a[n]);
return 0;
}
Discrete Centrifugal Jumps 单调栈+dp
最新推荐文章于 2021-10-06 19:03:21 发布