题意
题解
- 一开始想的是分情况讨论,比如当修改一个值后会影响几个波峰波谷的变化,又会增加几个新的波峰波谷,其实不用
- 因为只能改变一个值,所以我们直接枚举改变的值,改变后最优的值肯定是和左右端点相等的,对于枚举的每个点,我们只需要判断一下等于左端点减少的峰谷多还是等于右端点峰谷减少的多就可以了
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int t, n;
int a[N];
int check(int index) {
if (index == 1 || index == n) return 0;
if (a[index] > a[index + 1] && a[index] > a[index - 1]) return 1;
if (a[index] < a[index + 1] && a[index] < a[index - 1]) return 1;
return 0;
}
int main() {
cin >> t;
while (t--) {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
if (n == 1 || n == 2) {
cout << 0 << endl;
} else {
int res = 0;
for (int i = 2; i < n; i++) {
if (a[i] < a[i + 1] && a[i] < a[i - 1]) {
res++;
} else if (a[i] > a[i + 1] && a[i] > a[i - 1]) {
res++;
}
}
int manx = 1;
for (int i = 2; i < n; i++) {
int temp = a[i];
int cnt = check(i - 1) + check(i) + check(i + 1);
a[i] = a[i - 1];
int cnt1 = check(i - 1) + check(i) + check(i + 1);
a[i] = a[i + 1];
int cnt2 = check(i - 1) + check(i) + check(i + 1);
a[i] = temp;
int change = max(cnt - cnt1, cnt - cnt2);
manx = max(manx, change);
}
cout << max(0, res - manx) << endl;
}
}
return 0;
}