题目描述
即最小化相邻元素差的最大值。
题解
我们发现修改哪些数很难查找,显然需要二分答案这个最大值。
我们需要保证相邻两个元素的差都小于这个二分答案的数值,因此我们可以采用DP解决。
我们设f[i]f[i]f[i]表示一定保留第i个数字的情况下,最多能够保留多少个数字。
可以得到:f[i]=max(f[j])+1,∣a[i]−a[j]∣≤mid∗(i−j)f[i]=max(f[j])+1,|a[i]-a[j]|\leq mid*(i-j)f[i]=max(f[j])+1,∣a[i]−a[j]∣≤mid∗(i−j)
只要有一个f[i]是大于等于n-k的,表明有一种方案是合法的,则判断当前check函数为真。
时间复杂度:O(n2logW)O(n^2log W)O(n2logW)
代码如下:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 3000;
int n, k;
int a[N], f[N];
bool check(int x)
{
for (int i=1;i<=n;++i)
{
f[i] = 1;
for (int j=1;j<i;++j)
if (abs(a[i]-a[j]) <= (i-j)*x)
f[i] = max(f[j]+1,f[i]);
if (f[i] >= n-k) return 1;
}
return 0;
}
signed main(void)
{
scanf("%lld %lld", &n, &k);
for (int i=1;i<=n;++i)
scanf("%lld", a+i);
int l = 0, r = 1e16, mid;
while (l+1 < r)
{
mid = l+r >> 1;
check(mid) ? r = mid : l = mid;
}
printf("%lld\n", check(l) ? l : r);
return 0;
}