1. 程式人生 > 其它 >Hills And Valleys(貪心/列舉)

Hills And Valleys(貪心/列舉)

技術標籤: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>ai1&&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<ai1&&ai<ai+1,則 a i a_i ai為valley
題解:改動數時,改為 a i − 1 a_{i-1} ai1 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); } }