题意:

有一长度为n的正整数序列,你可以选择K个数字任意改变它,使得$max \{ a(i+1) - a(i) \} $ 最小,求最小值。

解法:

1.$O(n^2log(MAX_A) )$,考虑二分出$d = max \{ a(i+1) - a(i) \} $,这样考虑dp

$f(i,j)$表示前i个数字,末位的数字为j的时候最少修改了多少数字

$f(i,j) = min \{ f(i-1,k) \} (j-d ≤ k ≤ j+d,j = a(i))$

$f(i,j) = min \{ f(i-1,k) \} (j-d ≤ k ≤ j+d,j ≠ a(i))$

注意到有效的j只有$a(i),a(i)-d,a(i)+d$,从而对第二维离散化,同时用单调队列维护区段min即可

(维护方法,对于 前面出现的 比后面的数字小 的数一定不会出现在答案中,这样只要维护一个单调增的双端队列即可)

此方法常数过大,TLE

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ctime> #define LL long long
#define N 2010
#define INF 0x3f3f3f3f using namespace std; int n,m,K,minh,maxh,tots;
int a[N],a0[N*];
int f[N][N*],q[N*];
double tott; int Abs(int x)
{
if(x<) return -x;
return x;
} bool check(int d)
{
a0[]=;
for(int i=;i<=n;i++)
{
a0[++a0[]]=a[i];
if(a[i]-(LL)d>=(LL)minh) a0[++a0[]]=a[i]-d;
if(a[i]+(LL)d<=(LL)maxh) a0[++a0[]]=a[i]+d;
}
sort(a0+,a0+a0[]+);
m=;
for(int i=;i<=a0[];i++) if(a0[i]!=a0[i-]) a0[++m]=a0[i];
for(int i=;i<=m;i++) f[][i]=;
int t1=lower_bound(a0+,a0+m+,a[])-a0;
f[][t1]=;
int st=,ed=;
for(int i=;i<=n;i++)
{
st=, ed=;
int tmp=,minv=K+;
for(int j=;j<=m;j++)
{
while(tmp<=m && a0[tmp]<=a0[j]+d)
{
while(st<=ed && f[i-][q[ed]]>=f[i-][tmp]) ed--;
q[++ed]=tmp++;
}
while(st<ed && a0[q[st]]<a0[j]-d) st++;
int k=q[st];
if(a0[j]==a[i]) f[i][j]=f[i-][k];
else f[i][j]=f[i-][k]+;
minv = min(minv, f[i][j]);
if(f[i][j] + n-i <= K) return ;
}
if(minv > K) return ;
}
return ;
} int main()
{
freopen("test.txt","r",stdin);
while(~scanf("%d%d",&n,&K))
{
unsigned int l=,r=;
a0[]=;
minh=INF;
maxh=-INF;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
minh=min(minh,a[i]);
maxh=max(maxh,a[i]);
if(i>) r = max(r,(unsigned int)Abs(a[i]-a[i-]));
}
while(r-l>)
{
unsigned int mid=(l+r)>>;
if(check(mid)) r=mid;
else l=mid;
}
for(unsigned i=l;i<=r;i++)
if(check(i))
{
// cout << clock()/1000.0 << endl;
cout << i << endl;
break;
}
}
return ;
}

2.注意到方法一中第二维实际只有 j=a(i) 和其他的j ,两种j。

从而设$f(i)$表示前i个数字,数字i不改变 最少修改了多少数字。

这样有

$f(i) = min \{  f(j) + j-i-1 \}, ( \frac{|a(i)-a(j)|}{i-j} ≤ d )$

(i到j之间的数字全都改变)

小常数飘过

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ctime> #define LL long long
#define N 2010
#define INF 0x3f3f3f3f using namespace std; int n,m,K,a[N];
int f[N]; LL Abs(LL x)
{
if(x<) return -x;
return x;
} bool check(int d)
{
f[]=;
if(n-<=K) return ;
for(int i=;i<=n;i++)
{
f[i]=i-;
for(int j=;j<i;j++)
if(Abs(a[i]-(LL)a[j]) <= d*(LL)(i-j))
f[i] = min(f[i], f[j]+i-j-);
if(f[i]+n-i<=K) return ;
}
return ;
} int main()
{
// freopen("test.txt","r",stdin);
while(~scanf("%d%d",&n,&K))
{
LL l=,r=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
if(i>) r = max(r,(LL)Abs(a[i]-a[i-]));
}
while(r-l>)
{
LL mid=(l+r)>>;
if(check(mid)) r=mid;
else l=mid;
}
for(unsigned i=l;i<=r;i++)
if(check(i))
{
cout << i << endl;
break;
}
}
return ;
}

Levko and Array的更多相关文章

  1. [codeforces 360]A. Levko and Array Recovery

    [codeforces 360]A. Levko and Array Recovery 试题描述 Levko loves array a1, a2, ... , an, consisting of i ...

  2. CF360B Levko and Array (二分查找+DP)

    链接:CF360B 题目: B. Levko and Array time limit per test 2 seconds memory limit per test 256 megabytes i ...

  3. Codeforces 361D Levko and Array(二分)(DP)

    Levko and Array time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  4. 有意思的DP(CF360B Levko and Array)

    刚才面试了一个蛮有意思的DP题目,脑子断片,没写出来,不过早上状态还是蛮好的 一个长度为n的序列最多改变k次,使相邻两数之差绝对值的最大值最小 三维的dp我先尝试写一下 Codeforces 360B ...

  5. CodeForces - 361D Levko and Array

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

  6. Codeforces Round #210 (Div. 2) C. Levko and Array Recovery

    题目链接 线段树的逆过程,想了老一会,然后发现应该是包含区间对存在有影响,就不知怎么做了...然后尚大神,说,So easy,你要倒着来,然后再正着来,判断是不是合法就行了.然后我乱写了写,就过了.数 ...

  7. cf D. Levko and Array

    http://codeforces.com/contest/361/problem/D 用二分搜索相邻两个数的差的绝对值,然后用dp记录数改变的次数.dp[i]表示在i之前改变的次数,如果|a[i]- ...

  8. cf C. Levko and Array Recovery

    http://codeforces.com/contest/361/problem/C 这道题倒着一次,然后正着一次,在正着的一次的时候判断合不合法就可以. #include <cstdio&g ...

  9. codeforces 361 D. Levko and Array(dp+二分)

    题目链接:http://codeforces.com/contest/361/problem/D 题意:最多可以修改K次数字,每次修改一个数字变成任意值,C=max(a[i+1]-a[i]):求操作之 ...

随机推荐

  1. https双向认证訪问管理后台,採用USBKEY进行系统訪问的身份鉴别,KEY的证书长度大于128位,使用USBKEY登录

    近期项目需求,须要实现用USBKEY识别用户登录,採用https双向认证訪问管理后台管理界面,期间碰到过一些小问题,写出来给大家參考下. 1:前期准备工作 USBKEY 硬件:我买的是飞天诚信 epa ...

  2. 【分布式计算】DFS &amp;&amp; BigTable

    1.背景 分布式计算的发迹应该是google在2003年发表的三篇paper.各自是GFS.MapReduce.BigTable. 当中MapReduce大家都非常熟悉了.不懂的同学也能够看看我之前写 ...

  3. css hack(部分)

    一.去掉图片间隙:hack1.img{ display:block: }hack2.将<div></div>与<img>写在同一行 二.ie6双倍浮向(双倍边距)出 ...

  4. vue-router篇

    目录结构: -lib-vue.js -lib-vue-router.js -js-main.js -index.html 1.安装和基本配置 2.传参以及获取传参 3.子路由 4.手动访问和传参 5. ...

  5. FFMPEG SDK流媒体开发2---分离.mp4等输入流音视频而且进行解码输出

    对于FFMPEG SDK  提供的Demuxing 为我们实现多路复用  提供了非常多方便,以下的案案例 实现的是 分离一个媒体文件的音频 视频流 而且解码输出 到  不同的文件里. 对于音频被还原回 ...

  6. Git Xcode配置

    本文转载至 http://www.cnblogs.com/imzzk/p/xcode_git.html 感谢作者分享 Git源代码管理工具的出现,使得我们开发人员对于源码的管理更加方便快捷.至于Git ...

  7. c# 编程修改 wince 系统时间

    [StructLayout(LayoutKind.Sequential)] public struct SYSTEMTIME { public ushort wYear; public ushort ...

  8. mysql学习之基础知识

    一.什么是数据库 一般而言,数据库(Database)是按照数据结构来组织.存储和管理数据的仓库.我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢.所以,使用关系型数据库管理系统(RDB ...

  9. ElasticSearch(十一)批量CURD bulk

    1.bulk语法 POST /_bulk { "delete": { "_index": "test_index", "_type ...

  10. 把tomcat写到Windows系统服务器的服务中

    首先准备一个免安装的tomcat服务器,和一个Windows系统. 在“C:\Windows\SysWOW64”中找到cmd.exe的执行文件,以管理员身份启动: 进入到tomcat的bin文件夹, ...