D. Discrete Centrifugal Jumps(单调栈&&dp)

题目传送门

Discrete Centrifugal Jumps

题目大意

给你一个长度为n的数组h,求从 h [ 1 ] h[1] h[1] h [ n ] h[n] h[n]的最小步数
每次可以从i移到j, i < j i<j i<j移动方式为:
1、 i + 1 = j i+1=j i+1=j
2、 m a x ( h i + 1 , … , h j − 1 ) < m i n ( h i , h j ) max(h_{i+1},…,h_{j−1})<min(h_i,h_j) max(hi+1,,hj1)<min(hi,hj)
3、 m a x ( h i , h j ) < m i n ( h i + 1 , … , h j − 1 ) max(h_i,h_j)<min(h_{i+1},…,h_{j−1}) max(hi,hj)<min(hi+1,,hj1)

思路

无后效性的最优解,考虑dp,用单调栈维护转移
考虑 d p [ i ] dp[i] dp[i],其中 i i i表示到此位置需要的最小步数
使用非严格递增的单调栈维护第三种状态
使用非严格递减的单调栈维护第三种状态
最后记得判断即将入栈的元素是否与栈顶相同,相同需要弹出栈顶元素,因为题目要求的是<而不是<=

AC Code

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
#define endl '\n'
#define INF 0x3f3f
#define int long long
// #define TDS_ACM_LOCAL
const int N=5e5 +9;
int n, a[N];
int down[N], up[N], dp[N];
int totd, totu;
void solve(){
    cin>>n;
    for(int i=1; i<=n; i++) cin>>a[i];
    down[++totd]=1;up[++totu]=1;
    memset(dp, INF, sizeof(dp));
    dp[1]=0;
    for(int i=2; i<=n; i++){
        dp[i]=dp[i-1]+1;
        while(totd>0 && a[i]>a[down[totd]])
            dp[i]=min(dp[i], dp[down[totd--]]+1);
        while(totu>0 && a[i]<a[up[totu]])
            dp[i]=min(dp[i], dp[up[totu--]]+1);
        dp[i]=min(dp[i], min(dp[down[totd]], dp[up[totu]])+1);
        while(a[down[totd]]==a[i])    totd--;
        while(a[up[totu]]==a[i])      totu--;
        down[++totd]=i;up[++totu]=i;
    }
    cout<<dp[n]<<endl;
    return ;
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
    freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
    freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
    solve();
    return 0;
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值