1 条题解
-
0
标签:思维题 难度:中等
题目大意
有一排 (n) 个能量源,每个有一个权重 (a_i)。气团可以在任意位置生成,并向左或向右移动打通能量源。要求打通的顺序对应的权重序列必须是非递增的,求最少需要创建多少个气团。
解题思路
由于气团只能向左或向右单向移动,所以一段连续的单调序列(无论是递增还是递减)都只需要 1 团气就可以全部打通。
什么时候需要增加新的气团呢?只有当遇到“波峰”的时候(即先上升后下降的转折点)。因为一团气无法同时覆盖波峰左侧下降的坡和右侧上升的坡,而其他能量源只要不在波峰就能被波峰的高位气打通,必须且只需在波峰处断开。
所以,最少气团数 = 去重后数组中的“波峰”数量。
具体实现技巧:
- 去重:相邻相同的元素合并,避免平坦区间对上升/下降趋势的判断产生干扰。
- 补边界:在去重后的数组首尾各补一个极小值(如
0,因为题目保证 (a_i > 0))。这样一来,哪怕波峰出现在最左端或最右端,也能统一被公式a[i] > a[i-1] && a[i] > a[i+1]判断出来。
代码实现
void solve() { int n; scanf("%d", &n); // 一边读入,一边去重 (下标从 1 开始存) int m = 0; for (int i = 0; i < n; i++) { int x; scanf("%d", &x); if (m == 0 || x != a[m]) { a[++m] = x; } } // 首尾补 0,充当极小值边界 a[0] = 0; a[m + 1] = 0; int ans = 0; // 直接找波峰:大于左右两边 for (int i = 1; i <= m; i++) { if (a[i] > a[i - 1] && a[i] > a[i + 1]) { ans++; } } printf("%d\n", ans); }
- 1
信息
- ID
- 1248
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- (无)
- 递交数
- 20
- 已通过
- 9
- 上传者