题目链接: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;
}
京公网安备 11010502036488号