题目链接:https://vjudge.net/contest/396106#problem/B
思路:
这题显然是个dp,dp的思路也很简单~,就是dp[i]为到i的最短跳跃数,我们来主要分析一下它的状态转移方程
dp[i]能从三种情况转移过来,1.dp[i-1] 2.dpj13.dpj2??
那么显而易见,从j1+1到i都是i最小,这不就是单调栈干的事情嘛?单调栈是解决以某个数为最小/最大的区间。
这里需要注意,我在单调栈里去dp转移的时候,由于我栈的判断条件,导致我会对与我栈顶相同的一连串元素都转移,但按照题目是转移不过来的。
代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn = 3e5+7;

int n, a[maxn], dp[maxn], tmp;

stack<int> st1,st2;
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> a[i];

    dp[1] = 0;
    st1.push(1), st2.push(1);
    for(int i = 2; i <= n; i++){
        dp[i] = dp[i-1]+1;
        while(!st1.empty() && a[st1.top()] > a[i]){
            dp[i] = min(dp[i], dp[st1.top()]+1);
            st1.pop();
        }

        while(!st2.empty() && a[st2.top()] < a[i]){
            dp[i] = min(dp[i], dp[st2.top()]+1);
            st2.pop();
        }
        if(!st1.empty()&&!st2.empty())dp[i] = min(dp[i], min(dp[st1.top()], dp[st2.top()])+1);
        while(!st1.empty()&&a[st1.top()] == a[i]) st1.pop();
        while(!st2.empty()&&a[st2.top()] == a[i]) st2.pop();
        st1.push(i);
        st2.push(i);
    }

    cout << dp[n] << endl;
    return 0;
}