Solution #
First let’s consider the case where . could be lower or higher than . There can be multiple that satisfies the condition and we can observe the leftmost is the first that , let’s denote this , other between must satisfy that is the maximum value among . This can be solved using monotonic stack. Assume we store the indices in the stack, when adding a new index , all the indices that will be removed are a valid position to jump to , so we can do dp and update the minimum number of moves. The time complexity is .
The second case is similar.
Code #
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin>>n;
vector<int> a(n);
for(auto& it:a) cin>>it;
vector<int> dp(n,n);
dp[0]=0;
vector<int> h{0},l{0};
for(int i=1;i<n;i++){
dp[i]=min(dp[i],dp[i-1]+1);
while(!h.empty()&&a[i]>=a[h.back()]){
int x=a[h.back()];
h.pop_back();
if(a[i]>x&&!h.empty()) dp[i]=min(dp[i],dp[h.back()]+1);
}
while(!l.empty()&&a[i]<=a[l.back()]){
int x=a[l.back()];
l.pop_back();
if(a[i]<x&&!l.empty()) dp[i]=min(dp[i],dp[l.back()]+1);
}
h.push_back(i);
l.push_back(i);
}
cout<<dp[n-1];
return 0;
}