题干:
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 2
4 7 4 7 4
Output
0
Input
3 1
-100 0 100
Output
100
Input
6 3
1 2 3 7 8 9
Output
1
Note
In the first sample Levko can change the second and fourth elements and get array: 4, 4, 4, 4, 4.
In the third sample he can get array: 1, 2, 3, 4, 5, 6.
题目大意:
给一个n个元素的数组: a1, a2, ... , an。允许修改K个元素,使得max(abs(a[i]-a[i+1]))最小。(n<=2000)
Input
第一行输出两个整数n and k (1 ≤ k ≤ n ≤ 2000). 第二行输入n个整数a1, a2, ... , an ( - 109 ≤ ai ≤ 109).
Output
输出相邻两个元素之差的最小值
解题报告:
首先这个题肯定具有单调性,所以二分这个最小值,然后check是否可以在修改K个数以内来满足要求。
check(x)代表最小值数x的时候是否可以在修改K个数以内满足要求,也就是check中的相邻数的差的绝对值必须要<=x才行。check的时候选择dp。dp[i]代表在第i个数不变的情况下,前i个数满足相邻数<=x的最少改变的数。转移就是枚举前面每一个数当上一个不变的数,那中间的数都是变的,注意可以更新的条件,是中间的数都贪心的去这个最大值时,是否可行,你假设x是10,然后a[i-1]是1,a[i]是1e9,那怎么也转移不了对不对,所以贪心的策略,最大差值情况是刚好取公差为x的等差数列。然后取个最小值,并且默认在此条件下是否可以满足条件,也就是后面的数也全改变的情况下是否满足条件,满足直接return 1即可。
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e3 + 5;
int dp[MAX];
ll a[MAX];
int n,k;
bool ok(ll x) {for(int i = 1; i<=n; i++) {dp[i] = i-1;for(int j = 1; j<i; j++) {if(abs(a[i] - a[j]) <= (i-j)*x) 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++) cin>>a[i];ll l = 0,r = 2e9,mid,ans;while(l<=r) {mid = (l+r)>>1;if(ok(mid)) r = mid-1,ans = mid;else l = mid+1;} printf("%lld\n",ans);return 0 ;
}