Hills And Valleys(貪心/列舉)
阿新 • • 發佈:2021-01-13
技術標籤:Codeforces
題目
參考
題意:給定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);
}
}