Discrete Centrifugal Jumps
题意:i可以跳到j 当且仅当
思路:dp[i]为跳到 i 的最小代价 可以用单调栈来寻找哪些点可以跳到 i ;
//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int inf=2e18+100;
const int maxn=3e5+100;
int dp[maxn],a[maxn];
signed main()
{
IOS
stack<int>s1,s2;
int n;
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>a[i];
dp[i]=inf;
}
dp[1]=0;
for(int i=1; i<=n; i++)
{
dp[i]=min(dp[i],dp[i-1]+1);
while(!s1.empty()&&a[s1.top()]>=a[i])
{
int x=s1.top();
s1.pop();
if(!s1.empty()&&a[i]<a[x])dp[i]=min(dp[i],dp[s1.top()]+1);
}
while(!s2.empty()&&a[s2.top()]<=a[i])
{
int x=s2.top();
s2.pop();
if(!s2.empty()&&a[i]>a[x])dp[i]=min(dp[i],dp[s2.top()]+1);
}
s1.push(i);
s2.push(i);
}
cout<<dp[n]<<"\n";
}