Codeforces Round #210 (Div. 1) B. Levko and Array(dp 思维)

24 篇文章 0 订阅
B. 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 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
题意是给一个n个元素的数组ai,我们能修改k个数字,问怎么修改使得相邻两个数的差值的最大值最小。

看到最大值最小值我们很容易想到二分求解,但是问题是怎么check,贪心想不出来,dp的话也不好想,假设ai的值小一些我们还能枚举一下ai。看了别人的解法后觉得真的奇妙无穷,居然还能有这种dp方法,虽然没办法证明最小的性质,但是可以确定所有情况都被枚举到,
DP[i]代表前i个数字是符合条件的且不修改第i个数字的最少次数,然后枚举1<= j < i,如果 |ai-aj| <= mid * ( i - j) , 那么我们可以把(j , i)这个开区间的数字都修改掉,即dp[i] = min (dp[i] , dp[j ] + i - j - 1) 。这个正确性我也说不上来,感觉想法真的很好,但是注意,dp[i]并不是真正的答案,因为没有把修改第i个数字的情况考虑进去,实际上dp[i] + n - i 才是包含了i的情况。
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<set>
#include<map>
#include<time.h>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<iostream>
using namespace std;
#define  LONG long long
const LONG   INF=0x3f3f3f3f;
const LONG    MOD=1e9+7;
const double PI=acos(-1.0);
#define clr0(x) memset(x,0,sizeof x)
#define clrI(x) memset(x,-1,sizeof(x))
#define clr1(x) memset(x,INF,sizeof x)
#define clr2(x) memset(x,-INF,sizeof x)
#define EPS 1e-10
LONG  n ,k;
LONG  a[3000];
LONG  dp[3000];
bool check(LONG   x)
{
    dp[1] = 0;
    for(int i = 2; i <= n ;++ i)
    {
        dp[ i] = i - 1;
        for(int j =  i- 1 ;j >= 1; --j)
            if( abs(a[i] - a[j]) <= x * (i - j))
                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;
    if( n <=1)
    {
        cout<<0<<endl;
        return 0;
    }
    for(int i = 1; i<=n ;++ i)cin>>a[i] ;
    LONG  l = 0 , r = 3e9;
    LONG mid ;
    while(l < r)
    {
        mid = (l + r )/2 ;
        if(check(mid))
            r = mid  ;
        else l = mid + 1;
    }
    cout<<l<<endl;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值