cf D. Levko and Array
http://codeforces.com/contest/361/problem/D
用二分搜索相邻两个数的差的绝对值,然后用dp记录数改变的次数。dp[i]表示在i之前改变的次数,如果|a[i]-a[j]|<=(i-j)*mid 需要改变。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define LL __int64 5 using namespace std; 6 const LL inf=2000000000; 7 int dp[20000]; 8 int n,k; 9 LL a[20000]; 10 LL ABS(LL a) 11 { 12 if(a<0) return -a; 13 return a; 14 } 15 bool ok(LL c) 16 { 17 memset(dp,0,sizeof(dp)); 18 for(int i=1; i<=n; i++) 19 { 20 dp[i]=i; 21 for(int j=1; j<i; j++) 22 { 23 if(ABS(a[i]-a[j])<=(LL)(i-j)*c) 24 dp[i]=min(dp[i],dp[j]+(i-j-1)); 25 } 26 if(dp[i]+(n-i-1)<=k) return true; 27 } 28 return false; 29 } 30 31 int main() 32 { 33 while(scanf("%d%d",&n,&k)!=EOF) 34 { 35 for(int i=1; i<=n; i++) 36 { 37 scanf("%I64d",&a[i]); 38 } 39 LL l=0,r=inf; 40 while(l<=r) 41 { 42 LL mid=(l+r)/2; 43 if(ok(mid)) 44 { 45 r=mid-1; 46 } 47 else l=mid+1; 48 } 49 printf("%I64d\n",l); 50 } 51 return 0; 52 }