Levko and Array
题意:
有一长度为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的更多相关文章
- [codeforces 360]A. Levko and Array Recovery
[codeforces 360]A. Levko and Array Recovery 试题描述 Levko loves array a1, a2, ... , an, consisting of i ...
- CF360B Levko and Array (二分查找+DP)
链接:CF360B 题目: B. Levko and Array time limit per test 2 seconds memory limit per test 256 megabytes i ...
- Codeforces 361D Levko and Array(二分)(DP)
Levko and Array time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- 有意思的DP(CF360B Levko and Array)
刚才面试了一个蛮有意思的DP题目,脑子断片,没写出来,不过早上状态还是蛮好的 一个长度为n的序列最多改变k次,使相邻两数之差绝对值的最大值最小 三维的dp我先尝试写一下 Codeforces 360B ...
- CodeForces - 361D Levko and Array
Discription Levko has an array that consists of integers: a1, a2, ... , an. But he doesn’t like this ...
- Codeforces Round #210 (Div. 2) C. Levko and Array Recovery
题目链接 线段树的逆过程,想了老一会,然后发现应该是包含区间对存在有影响,就不知怎么做了...然后尚大神,说,So easy,你要倒着来,然后再正着来,判断是不是合法就行了.然后我乱写了写,就过了.数 ...
- cf D. Levko and Array
http://codeforces.com/contest/361/problem/D 用二分搜索相邻两个数的差的绝对值,然后用dp记录数改变的次数.dp[i]表示在i之前改变的次数,如果|a[i]- ...
- cf C. Levko and Array Recovery
http://codeforces.com/contest/361/problem/C 这道题倒着一次,然后正着一次,在正着的一次的时候判断合不合法就可以. #include <cstdio&g ...
- codeforces 361 D. Levko and Array(dp+二分)
题目链接:http://codeforces.com/contest/361/problem/D 题意:最多可以修改K次数字,每次修改一个数字变成任意值,C=max(a[i+1]-a[i]):求操作之 ...
随机推荐
- javascript 高级编程系列 - 继承
1. 原型链继承 (缺点:子类继承父类的引用类型的属性值会在各个实例中共享,创建子类实例时无法向父类构造函数传递参数) // 定义父类构造函数 function SuperClass(father, ...
- 使用".."指定git提交范围与"..."指定git提交范围的区别
http://blog.csdn.net/hansel/article/details/8952967 使用".."(两个点)和"..."(三个点)都可以指定一 ...
- Android组件系列----ContentProvider内容提供者【4】
(4)单元測试类: 这里须要涉及到另外一个知识:ContentResolver内容訪问者. 要想訪问ContentProvider.则必须使用ContentResolver. 能够通过ContentR ...
- linux shell 的前世今生和流行BASH SHELL的特点
前言 shell作为用户和操作系统内核交互的接口,也不断的在发展迭代.shell的发展也离不开unix/linux 系统的发展.并且在开源社区对shell的发展也起到了推动作用. 内容思维导图简介 发 ...
- shift:解决shell编程中的入渗问题
我说过了,shell是我的常规武器,目前虽然还不纯熟,但是我爱shell这门语言,在Linux下面混,总要写脚本.程序员是有基因,对编程语言是有偏好的,你让我写C代码,我会觉得很爽,会有困难,会有痛苦 ...
- 多线程(C++)临界区Critical Sections
一 .Critical Sections(功能与Mutex相同,保证某一时刻只有一个线程能够访问共享资源,但是不是内核对象,所以访问速度比Mutex快,但是没有等待超时的功能,所以有可能导致死锁,使用 ...
- Ubuntu 13.10上用户怎样获得root权限,用户怎样获得永久root权限,假设配置root登录
一.用户怎样获得root权限: 1. 进入terminal 2. 输入sudo passwd root 并设置password,提示要你输入两次password.自己设定password,一定要 ...
- Vue使用axios
main.js------------------- import axios from "axios"; import qs from "qs"; imp ...
- 在c代码中获取用户环境变量
1 extern char ** environ 这是一个字符串数组,最后一个元素是null,即\0. 2 在代码中的使用方法 直接extern char **environ,然后 直接environ ...
- 第三章 Java 的基本程序设计结构
1.Java基本数据类型 Java中一共有8种基本数据类型. 4种整形:int-4字节.long-8字节.short-2字节.byte-1字节 2中浮点型:float-4字节.double-8字节 1 ...