標籤:acm codeforces dp
題目連結
- 題意:
n、k,表示n個點,每個點有一個值,記c = max(abs(n[i] - n[i + 1])),要求只能將數組中的至多k個元素值改變(變成任意值),求c的最小值
- 分析:
可以二分一下c的值,求當前數組是否能改變至多k個數切c小於二分值。判斷的話可以採用DP,dp[i]表示n[i]不改變時候,滿足c <= 二分值時候需要改變的數字個數。
- 注意:
DP的時候,dp[i] -> dp[j]時候,如果可以轉移,那麼直接dp[j] = min(dp[j], dp[i] + j - i + 1),也就是說認為i到j之間的元素都進行了改變。這個正確性可以這樣解釋:如果中間有一個元素剛好不需要改變,那麼在DPi轉移到這個元素然後再轉移到j的時候,答案比直接從i再到j要優,所以這樣轉移是正確的。
const int maxn = 2100;int ipt[maxn], dp[maxn];int n, k;int check(LL Max){ REP(i, n) dp[i] = i; REP(i, n) REP(j, i) if (abs(ipt[j] - ipt[i]) <= Max * (i - j)) dp[i] = min(dp[i], dp[j] + i - j - 1); REP(i, n) if (dp[i] + n - i - 1 <= k) return true; return false;}int main(){ while (~RII(n, k)) { REP(i, n) RI(ipt[i]); LL l = 0, r = 2e9, m; while (l <= r) { m = (l + r) >> 1; if (check(m)) r = m - 1; else l = m + 1; } cout << l << endl; } return 0;}
Codeforces Round #210 (Div. 1)——Levko and Array