cf360 B. Levko and Array(二分答案,dp判斷)
阿新 • • 發佈:2022-01-15
題意:
修改陣列中的不超過k個數,最小化相鄰數之差的絕對值的最大值。
k <= n <= 2000
思路:
\(f(i)\) 表示第 \(i\) 個數不變,前 \(i\) 個數合法,至少要改變幾個數。
初始化 \(f(i)=i-1\) 表示前面的數都改變。列舉 \(i\) 之前的所有 \(j\),把 \([j+1,i-1]\) 都改變,改成單調增或者單調減,那麼 \(|a_i-a_j|/(i-j)\le ans\) 時ans合法。
對於每個 \(f(i)\),當 \(f(i)+n-i\le k\) 時有答案。即後面的數都改變。
#include <bits/stdc++.h> using namespace std; using ll = long long; const int N = 2010; int n, k, a[N], f[N]; bool pd(ll x) { for(int i = 1; i <= n; i++) { f[i] = i - 1; for(int j = 1; j < i; j++) if(abs(a[i]-a[j]) <= x * (i-j)) f[i] = min(f[i], f[j] + i-j-1); if(f[i] + n-i <= k) return 1; } return 0; } signed main() { scanf("%d%d", &n, &k); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); ll l = 0, r = 2e9; while(l < r) { ll mid = l + r >> 1; //注意開ll if(pd(mid)) r = mid; else l = mid + 1; } printf("%lld", l); return 0; }