题目链接: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; }