题意:给定n个数和一个k,可以改变k个值,最小化相邻两项的差的绝对值的最大值
题解:
最大值最小,可以考虑二分答案;
然后考虑保留哪些关键点不变,dp[i]表示第i个点不变,
如果abs(a[i]-a[j])<=x*(i-j),则我们可以从第j个点转移过来,中间的点分布在线段IJ上
然后看是否超过k个
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define maxn 2005 4 using namespace std; 5 int n,k; 6 ll a[maxn]; 7 int dp[maxn]; 8 bool check(ll x) 9 { 10 memset(dp,0,sizeof(dp)); 11 int ans=n; 12 for(int i=1;i<=n;++i) 13 { 14 dp[i]=i-1; 15 for(int j=1;j<i;++j)if(abs(a[i]-a[j])<=x*(i-j)) 16 dp[i]=min(dp[i],dp[j]+(i-j-1)); 17 ans=min(ans,dp[i]+n-i); 18 } 19 return (ans<=k); 20 } 21 int main() 22 { 23 scanf("%d%d",&n,&k); 24 for(int i=1;i<=n;++i)scanf("%I64d",&a[i]); 25 ll l=0,r=2000000000,ans=r+1; 26 while(l<=r) 27 { 28 int mid=(l+r)>>1; 29 if(check(mid))ans=mid,r=mid-1; 30 else l=mid+1; 31 } 32 printf("%d ",ans); 33 return 0; 34 }