题目
参考
题意:给定n个数,要求改动一个数(可以改成任意数),使得改动后这n个数的hill数和valley数的和最小。
hill:如果
a
i
>
a
i
−
1
&
&
a
i
>
a
i
+
1
a_i>a_{i-1}\&\&a_i>a_{i+1}
ai>ai−1&&ai>ai+1,则
a
i
a_i
ai为hill
valley:如果
a
i
<
a
i
−
1
&
&
a
i
<
a
i
+
1
a_i<a_{i-1}\&\&a_i<a_{i+1}
ai<ai−1&&ai<ai+1,则
a
i
a_i
ai为valley
题解:改动数时,改为
a
i
−
1
a_{i-1}
ai−1或
a
i
+
1
a_{i+1}
ai+1为最优。枚举改动的所有情况,取最优。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 300010;
int n;
int a[maxn];
int check(int i) {
if (i == 0 || i == n - 1) return 0;
if (a[i] > a[i-1] && a[i] > a[i+1])
return 1;
if (a[i] < a[i-1] && a[i] < a[i+1])
return 1;
return 0;
}
int cal(int i) {
return check(i-1) + check(i) + check(i+1);
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d", &a[i]);
}
int num = 0;
for (int i = 1; i < n - 1; ++i) {
num += check(i);
}
int mx = 0;
for (int i = 1; i < n - 1; ++i) {
int tmp = a[i];
int res = cal(i);
a[i] = a[i-1];
int mn = cal(i);
a[i] = a[i+1];
mn = min(mn, cal(i));
mx = max(mx, res - mn);
a[i] = tmp;
}
// printf("num:%d mx:%d\n", num, mx);
printf("%d\n", num - mx);
}
}