CF360B題解

GCSG01發表於2024-10-14

簡述題意

定一個數列 \(a\),可以對其中的元素做至多 \(k\) 次修改,每次修改可以將數列中的一個數改成另一個。
求經過修改後,\(max_{i=1}^{n} |a_i-a_{i-1}|\)

思路

考慮二分答案,對於 check 函式,我們可以利用 dp 進行求解。
由於修改不太好想,我們可以把問題轉換為讓不被修改的數最多。容易發現,如果有 \(a_1,a_2,a_3\) 3個數都需要修改,當 \(a_2\) 有值可以使得這兩個差都滿足條件,我們就可以稍改一個,即條件為 \(|a_i-a_j|<(i-j)\times x\)

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,k;
int a[2005];
int dp[2005];
bool check(int x)
{
	for(int i=1;i<=n;i++)
    {
		dp[i]=1;
		for(int j=1;j<i;j++)
			if(abs(a[i]-a[j])<=x*(i-j))
                dp[i]=max(dp[i],dp[j]+1);
		if(dp[i]>=n-k) return true;
	}
	return false;
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>k;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    int l=-1,r=2e9;//不知道為什麼,l設為0或其他數都過不了,只有設為-1才能過
    while(l+1<r)
    {
        int mid=(l+r)>>1;
        if(check(mid))r=mid;
        else l=mid;
    }
    cout<<r;
    return 0;
}