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]):求操作之 ...
随机推荐
- mysql: Data source rejected establishment of connection, message from server: "Too many connections"
http://www.oschina.net/question/558677_66703 com.mysql.jdbc.exceptions.MySQLNonTransientConnectionEx ...
- http协议的Last-Modified
$modified_time = $_SERVER['HTTP_IF_MODIFIED_SINCE']; if (strtotime($modified_time) + 3600 > time( ...
- DDR硬件设计要点详解(包括电源部分)
转自 http://www.fairchildic.org/module/forum/thread-658-1-1.html (原帖包括详细的附件内容) 1. 电源 DDR的电源可以分为三类A.主电源 ...
- 不使用while,for,if等实现加法
不使用if, while,for,switch等实现从1到10的加法 解:这里使用静态函数和静态变量实现,利用类似的方法也能够实现从1打印到1000 class TheSum{ public: The ...
- Protostuff具体解释
Protostuff具体解释 作者:chszs,未经博主同意不得转载. 经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs 一.Protostuff介绍 Proto ...
- krpano HTML5 Viewer可以实现全景展示
http://www.krpano360.com/ krpanp 陀螺仪调取 全景展示
- Spring LDAP
LDAP Spring LDAP 使用 - Sayi像秋天一样优雅 - 开源中国社区 http://docs.spring.io/spring-ldap/docs/current/reference/ ...
- 如何在微信小程序中使用字体图标
微信小程序中,在image标签里,可以在src中引用本地文件,但是background设置背景图或者使用字体图标的时候,却不能引用本地文件,只能用url地址的图片或字体,或者使用base64编码后的格 ...
- 记录一次在 VirtualBox的添加共享windows文件后,发现没有共享文件的事
在VirtualBox设置完桥接添加ip后,在设备中添加共享windows文件,“e:\work ”,发现共享目录没有文件.使用了各种reboot之后,还是没有发现共享文件夹,重新设置还是不行,用mo ...
- ffmpeg mediacodec 硬解初探
ffmpeg mediacodec 硬解初探 1编译: ffmpeg自3.1版本加入了android mediacodec硬解支持,解码器如图 硬件加速器如图(还不清楚硬件加速器的功能) 编译带h26 ...