codeforces D. Levko and Array(二分加dp) 挺好的一个题

来源:互联网 发布:mac 战网 改台服 编辑:程序博客网 时间:2024/06/05 07:33
D. Levko and Array
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Levko has an array that consists of integers: a1, a2, ... , an. But he doesn’t like this array at all.

Levko thinks that the beauty of the array a directly depends on value c(a), which can be calculated by the formula:

The less value c(a) is, the more beautiful the array is.

It’s time to change the world and Levko is going to change his array for the better. To be exact, Levko wants to change the values of at most k array elements (it is allowed to replace the values by any integers). Of course, the changes should make the array as beautiful as possible.

Help Levko and calculate what minimum number c(a) he can reach.

Input

The first line contains two integers n and k (1 ≤ k ≤ n ≤ 2000). The second line contains space-separated integers a1, a2, ... , an( - 109 ≤ ai ≤ 109).

Output

A single number — the minimum value of c(a) Levko can get.

Examples
input
5 24 7 4 7 4
output
0
input
3 1-100 0 100
output
100
input
6 31 2 3 7 8 9
output
1
Note

In the first sample Levko can change the second and fourth elements and get array: 44444.

In the third sample he can get array: 123456.

题意:  给你n个数 你最多改变其中的k个数使得 两个相邻的数之间的差的绝对值最小。

思路:  二分 答案 (二分任意差的绝对值 看在mid的情况下是否符合情况 如果符合情况 那么r=mid-1  否则l=mid+1 ) 

而在判断的时候就要用到dp   dp[i] 表示在不改动a[i] 的情况下 前i个数需要改动的个数。

首先dp[1]=0;  那么dp[i] =  ?  当然取决于前边的情况  如果到j需要改动dp[j] 个数 那么对于i 就有dp[i]=dp[j]+ i-j-1 ;  表示(j,i)的数都需要改变(开区间)  而改变的条件就是a[i]和

a[j] 的差值 小于等于(i-j)*mid     而是否符合条件只需要看dp[i]+n-i  是否小于等于k  

d代码: 

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#define N 2005using namespace std;typedef long long ll;const ll inf =1e15;int n,k;ll a[N];ll dp[N];int jud(ll num){memset(dp,inf,sizeof(dp));dp[1]=0;for(int i=2;i<=n;i++){dp[i]=i-1;for(int j=1;j<i;j++){if(abs(a[i]-a[j])<=(i-j)*num){dp[i]=min(dp[i],dp[j]+i-j-1);}}if(dp[i]+n-i<=k) return 1;}return 0;}int main(){cin>>n>>k;for(int i=1;i<=n;i++) scanf("%lld",&a[i]);ll l ,r,mid;l=0; r=inf;ll ans=0;while(l<=r){mid=(l+r)>>1;//printf(" mid : %lld\n",mid);if(jud(mid)){ans=mid;r=mid-1;}else l=mid+1;}printf("%lld\n",ans);return 0;} /*20 17-5 -9 11 -7 -17 -8 0 -14 -20 -15 7 -13 0 -3 -14 0 9 -10 6 -195 1-1000000000 1000000000 -1000000000 1000000000 -1000000000*/