E - 愚公移山

这篇文章讲述了如何利用后缀数组算法解决一个关于山峰高度排序的问题,目标是找到分割山脉为非降序序列所需的最少连续区间数量。给出山峰高度列表后,通过计算后缀最小值确定分割点,从而求得最大区间数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传说上天终于被愚公的精神所感动,于是天神给愚公出了一道绝世难题,只需要他或是愚公的后人中有人可以解决这道绝世难题就可以帮助世人移走这座大山。问题如下:
一共有 n 座山,山从南到北依次排开,这 n 座山的高度参差不齐看上去十分杂乱,因此天神们决定将这 n 座山重新排列 变为从南到北的一个非降序序列,天神们有一个法术可以将一段连续区间内的山通过排序改变顺序变为一个非降序序列,但是法术的消耗十分巨大,并且十分耗时,他们决定将这 n 座大山分为 k 个不相交的连续区间(每座山都会在一段区间里),这样只需要派出 k 个天神使用一次法术就可以将所有山变为一个非降序序列。请问 k 的最大值为几?
而你身为愚公的第114514代曾孙,并且成为了一个ACMer,你决定使用计算机解决这个问题。

输入
第一行输入一个整数 n (1 ≤ n ≤ 1e6 ) 表示有n座山之后一行 n 个整数 (0 ≤ ai ≤1e9)  表示从南向北每一座山的高度。

输出
输出一个整数 k 表示 可以分成的最大区间数量。

Input
6
1 3 2 7 5 4

Output
3

解析:
当前点a[i],如果在这之后没有比它更小的数,那说明可以从此处断开,成为一个独立的区间。
所以可以用一个后缀数组记录当前点从后往前的最小值。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
typedef pair<int, int> PII;
const double PI = acos(-1.0);
const int N=1e6+10;
int n;
int a[N],p[N];
void solve()
{
    cin>>n;
    for (int i=1;i<=n;i++) cin>>a[i];
    p[n+1]=2e9;
    for (int i=n;i>=1;i--)
    {
        p[i]=min(p[i+1],a[i]);
    }


    int ans=0;
    int l=0;
    for (int i=1;i<=n;i++)
    {
        l=max(l,a[i]);
        if (l<=p[i+1]) ans++,l=p[i];
    }

    cout<<ans;
}
signed main()
{
    ios;
    int T = 1;
    //cin>>T;
    while (T--) solve();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值