1 条题解
-
0
Balancing 详细题解
题目分析
核心题意
给定一个相邻元素互不相等的数组 ,要求用最少的操作次数将数组变成严格递增数组。
每次操作规则: 选择区间 ,将这个区间内的数整体替换,替换后必须保留原区间内相邻元素的大小关系(原 则新数也必须 ;原 则新数也必须 )。
求最小操作次数。
关键观察(核心突破口)
- 严格递增数组的本质:所有相邻元素都必须满足 。
- 操作的作用:一次操作可以修复一段连续的「下降关系」,但无法改变区间内的大小关系,只能修改数值。
- 核心定义:我们把数组中所有 的位置称为下降点,记总下降点数量为 。
标程逻辑深度解析
步骤1:统计所有下降点
遍历数组,统计所有满足 的位置:
- 每遇到一个下降点,
ans += 1 - 记录第一个下降点的左位置
pos1(第一个 的 ) - 记录最后一个下降点的右位置
pos2(最后一个 的 )
步骤2:判断两种情况
标程核心判断公式:
if ((ans & 1) || (pos1 && a[pos2] - a[pos1] < pos2 - pos1)) 答案 = (ans >> 1) + 1 else 答案 = ans >> 1翻译为数学语言:
- 情况1:下降点数量 是奇数 最小操作次数
- 情况2:下降点数量 是偶数,但首尾下降区间无法直接拼接成严格递增 (即 ) 最小操作次数
- 情况3:下降点数量 是偶数,且可以直接拼接 最小操作次数
原理推导
1. 下降点的分组规律
一次操作最多可以修复 2 个连续的下降点:
- 下降点是 这种连续下降段
- 一次操作修改 ,可以把它改成严格递增,一次性修复 2 个下降点
因此:
- 偶数个下降点:理论最少操作数
- 奇数个下降点:必须多一次操作,最少操作数
2. 偶数下降点的特殊判断
即使下降点是偶数,也可能无法用 次完成: 需要满足首尾可拼接严格递增:
- :第一个下降的左位置
- :最后一个下降的右位置
如果不满足,说明无法一次合并修复,必须额外加 1 次操作。
标程代码逐行解释
// 统计下降点 ans,记录第一个下降左pos1,最后一个下降右pos2 for (ll i = 1;i < n;i += 1) if (a[i] > a[i + 1]){ ans += 1,pos2 = i + 1; if (!pos1) pos1 = i; } // 核心判断 // 1. 下降点奇数 OR 2. 偶数但无法拼接 → 答案=ans/2 +1 if ((ans & 1) || (pos1 && a[pos2] - a[pos1] < pos2 - pos1)) printf("%lld\n",(ans >> 1) + 1); // 偶数且可拼接 → 答案=ans/2 else printf("%lld\n",ans >> 1);ans & 1:判断奇数(二进制最后一位为1)ans >> 1:等价于整数除法pos1:第一个下降点左侧位置pos2:最后一个下降点右侧位置
样例验证(对照输入输出)
样例1
输入:
3 3 2 1- 下降点:、 → (偶数)
- 判断:
- 答案: ✔️
样例2
输入:
3 3 1 2- 下降点: → (奇数)
- 答案: ✔️
样例3
输入:
4 -2 -5 5 2- 下降点:、 → (偶数)
- 答案: ✔️
样例4
输入:
7 1 9 1 9 8 1 0- 下降点:、、、 →
- 判断不满足拼接条件 → 答案 ✔️
复杂度分析
- 时间复杂度: 每个测试用例仅遍历一次数组,总长度不超过 ,完全符合时间限制。
- 空间复杂度: 存储数组即可,无额外空间开销。
总结
- 核心指标:统计数组中下降点数量 ( 的次数)。
- 判断规则:
- 下降点为奇数 答案
- 下降点为偶数但无法拼接 答案
- 下降点为偶数且可拼接 答案
- 拼接条件:。
- 1
信息
- ID
- 6390
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者