河南萌新联赛2026第(一)场:河南工业大学G题题解
侧边栏壁纸
  • 累计撰写 9 篇文章
  • 累计收到 2 条评论

河南萌新联赛2026第(一)场:河南工业大学G题题解

llwqs
2026-07-28 / 0 评论 / 9 阅读 / 正在检测是否收录...

核心思路:逆向思维与差分思想

这道题表面上是一个复杂的“区间修改”问题,但如果我们转换视角,将其逆向思考,就会变得非常直观。 题目链接

1. 逆向思维:从“削减”到“堆叠”

题目要求将一排参差不齐的树全部减为 0,每次操作可以对一段连续的树高度减 1。由于减法和加法是完全可逆的,我们可以把这个问题等价转换为:
初始时所有树的高度都是 0,最少需要多少次“对一段连续的树高度加 1”的操作,才能恰好拼凑出题目给定的目标高度?

2. 直观想象:画山峰

想象我们在一张白纸上画一排柱子(山峰)。

  • 当我们要画第一棵树(高度为 $a_0$)时,我们必须从它开始,连续发起 $a_0$ 次加 1 的操作。
  • 当画到第二棵树(高度为 $a_1$)时,为了操作次数最少,我们会尽量让之前的操作“顺带”覆盖过来。

    • 如果 $a_1 > a_0$,说明之前延续过来的操作不够用,我们必须额外发起 $a_1 - a_0$ 次仅从第二棵树开始的新操作。
    • 如果 $a_1 \le a_0$,说明之前延续过来的操作已经足够覆盖当前树,甚至还会有多余的操作在这里自然“结束”,我们完全不需要增加新的操作次数。

3. 提炼规律

通过上述过程,我们可以得出一个普适的规律:只有当当前位置的树比前一棵树高时,我们才需要发起新的操作。
新发起的操作次数,恰好等于 当前高度 - 前一个高度。如果当前树比前一棵树矮或一样高,则不需要增加操作次数。

因此,整个问题的答案,就是遍历数组,累加所有“上升沿”的高度差。

完整代码

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    cin>>n;
    vector<long long> a(n);
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    long long ans=0;
    long long prev=0;
    for(int i=0;i<n;i++){
        if(a[i]>prev){
            ans+=(a[i]-prev);
        }
        prev=a[i];
    }
    cout<<ans<<endl;
    return 0;
}
0

评论 (0)

取消