题目描述

  给定一个长度为$n$的格子序列$x_1,x_2,...,x_n$。每一次$Lyra$可以选择向左跳到任意一个还没到过的位置,也可以向右跳到任意一个还没到过的位置。如果现在$Lyra$在格子$i$,她下一步跳向格子$j$,那么这次跳跃的花费为$|x_i-x_j|$。注意,跳意味着格子$i$和格子$j$中间其他的格子都不会被这次跳跃影响。并且,$Lyra$不应该跳出边界。
  $Lyra$的初始位置在格子$s$。$Lyra$将会在到访过所有格子恰好一次之后,在某个位置停下来,这样就完成了任务。
  $Lyra$想知道如果她一共向左跳了$L$次,那么她要完成任务的最小总花费是多少,并希望你输出任意一种花费最小的方案。显然如果$Lyra$向左走了$L$次,那一定会向右走$n-L-l$次。
  特殊的,如果$Lyra$没有办法完成任务,请输出一行$-1$。


输入格式

第一行,三个整数$n,L,s$,分别表示序列的大小,向左走的次数,和初始位置。
第二行,$n$个数字,表示序列$x_i$。


输出格式

第一行,一个数字,表示答案。
如果能完成任务,则第二行,输出$n-1$个数字,表示方案。注意,$Lyra$初始的位置已经确定了,所以不要输出。


样例

样例输入:

3 1 2
1 2 3

样例输出:

3
1 3


数据范围与提示

样例解释:

$Lyra$一开始在$2$的位置,$2\rightarrow 1\rightarrow 3$的路径中,$Lyra$一共向左走了$1$次,花费为$|2-1|+|1-3|=3$。

数据范围:

测试点$1\sim 2,n\leqslant 8,0\leqslant x_i \leqslant 10^9$。
测试点$3\sim 8,n\leqslant 20,0\leqslant x_i \leqslant 10^9$。
测试点$9\sim 10,n\leqslant 2\times 10^5,x_i =i$。
测试点$11\sim 20,n\leqslant 2\times 10^5,0\leqslant x_i \leqslant 10^9$。
对于所有数据,都满足$x_1<x_2<...<x_{n-1}<x_n,1\leqslant s\leqslant n,0\leqslant L\leqslant n-1$。


题解

先来考虑$-1$的情况,分为两种情况。

  $\alpha.L=0,s\neq 0$,显然我们无论如何都不能走到$s$左边的点。

  $\beta.L=n-1,s\neq n$,则我们向右走的步数为$0$,其它类比上面。

再来考虑一般情况。

$x_1<x_2<...<x_{n-1}<x_n$是一个非常好的性质,也就是说,尽可能少的覆盖区间一定是最优的;这里所说的区间是指假如我从$l$走到了$r$,那么就将区间$[l,r]$覆盖了一遍,也就是付出了$x_r-x_l$的代价(假设$l$在左,$r$在右)。

那么考虑如何选择这条路径。

这时候我们分为一开始向右走和一开始向左走,显然这两种情况无非就是将区间$reverse$一下,那么我们现在只考虑向左走的情况。

起点已经固定为$s$,不妨设终点为$t$,那么路径一定类似下图$\downarrow$

设在$s$左侧向左走了$l_1$步,在$t$右侧向右走了$l_2$步,那么可以通过调整在$s$左侧向左走的步数来满足$t$的右侧。

如果都无法满足,则意味着我们需要在$s\sim t$这段区间再向左走,如下图$\downarrow$

那么这样一定不是最优的,因为存在方案$s\sim t'$一定比$s\sim t$更优。

于是可以枚举每一个$t$,去最小即可。

路径直接构造就好了。

一开始向右走的情况同理,两种方案取$\min$即可。

时间复杂度:$\Theta(n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int n,l,s;
int xl[200001],xr[200001],top;
bool vis[200001];
int ansl,ansr,quel[200001],quer[200001],pos[200001];
pair<int,int> sta[200001];
void solvel()
{
if(l<s)
{
for(int i=s-1;i>=s-l+1;i--)quel[++quel[0]]=i;
for(int i=1;i<=s-l;i++)quel[++quel[0]]=i;
for(int i=s+1;i<=n;i++)quel[++quel[0]]=i;
ansl=xl[s]+xl[n]-(xl[1]<<1);
return;
}
if(l+1==n-1)
{
for(int i=s-1;i;i--)quel[++quel[0]]=i;
for(int i=n;i>s;i--)quel[++quel[0]]=i;
ansl=((xl[n]-xl[1])<<1)+xl[s]-xl[s+1];
return;
}
for(int i=s+2;i<n;i++)sta[++top]=make_pair(xl[i]-xl[i-1],i);
sort(sta+1,sta+top+1);
for(int i=1;i<=top;i++)pos[sta[i].second]=i;
int res=0;
for(int i=1;i<=l-s+1;i++)res+=sta[i].first;
int mx=res<<1,t=n,j=l-s+1;
for(int i=n-1,flag=l-s+1;i>=n-l+s-1;i--)
{
if(pos[i]<=flag)res-=sta[pos[i]].first;
else res-=sta[flag--].first;
while(flag&&i<=sta[flag].second)flag--;
if(mx>(res<<1)+xl[n]-xl[i]){mx=(res<<1)+xl[n]-xl[i];t=i;j=flag;}
}
for(int i=s-1;i;i--)quel[++quel[0]]=i;
for(int i=s+2;i<t;i++)if(pos[i]<=j)vis[i]=1;
for(int i=s+1;i<t;i++)
{
if(!vis[i+1])quel[++quel[0]]=i;
else
{
int flag=i+1;
while(vis[flag])flag++;
for(int j=flag-1;j>=i;j--)quel[++quel[0]]=j;
i=flag-1;
}
}
for(int i=n;i>=t;i--)quel[++quel[0]]=i;
ansl=xl[s]+xl[n]-2*xl[1]+mx;
}
void solver()
{
top=0;
memset(vis,0,sizeof(vis));
if(l+2>s)
{
for(int i=n-s;i>=l-s+3;i--)quer[++quer[0]]=i;
for(int i=1;i<=l-s+2;i++)quer[++quer[0]]=i;
for(int i=n-s+2;i<=n;i++)quer[++quer[0]]=i;
ansr=xr[n-s+1]+xr[n]-(xr[1]<<1);
return;
}
if(l==1)
{
for(int i=n-s;i;i--)quer[++quer[0]]=i;
for(int i=n;i>n-s+1;i--)quer[++quer[0]]=i;
ansr=((xr[n]-xr[1])<<1)+xr[n-s+1]-xr[n-s+2];
return;
}
for(int i=n-s+3;i<n;i++)sta[++top]=make_pair(xr[i]-xr[i-1],i);
sort(sta+1,sta+top+1);
for(int i=1;i<=top;i++)pos[sta[i].second]=i;
int res=0;
for(int i=1;i<=s-l-1;i++)res+=sta[i].first;
int mx=res<<1,t=n,j=s-l-1;
for(int i=n-1,flag=s-l-1;i>=l-s+n+1;i--)
{
if(pos[i]<=flag)res-=sta[pos[i]].first;
else res-=sta[flag--].first;
while(flag&&i<=sta[flag].second)flag--;
if(mx>(res<<1)+xr[n]-xr[i]){mx=(res<<1)+xr[n]-xr[i];t=i;j=flag;}
}
for(int i=n-s;i;i--)quer[++quer[0]]=i;
for(int i=n-s+3;i<t;i++)if(pos[i]<=j)vis[i]=1;
for(int i=n-s+2;i<t;i++)
{
if(!vis[i+1])quer[++quer[0]]=i;
else
{
int flag=i+1;
while(vis[flag])flag++;
for(int j=flag-1;j>=i;j--)quer[++quer[0]]=j;
i=flag-1;
}
}
for(int i=n;i>=t;i--)quer[++quer[0]]=i;
ansr=xr[n-s+1]+xr[n]-2*xr[1]+mx;
}
int main()
{
scanf("%d%d%d",&n,&l,&s);
for(int i=1;i<=n;i++)
{
scanf("%d",&xl[i]);
xr[n-i+1]=-xl[i];
}
if((!l&&s!=1)||(l==n-1&&s!=n)){puts("-1");return 0;}
solvel();solver();
if(ansl<ansr)
{
printf("%d\n",ansl);
for(int i=1;i<n;i++)printf("%d ",quel[i]);
}
else
{
printf("%d\n",ansr);
for(int i=1;i<n;i++)printf("%d ",n-quer[i]+1);
}
return 0;
}

rp++

[CSP-S模拟测试]:Travel(贪心+构造)的更多相关文章

  1. [CSP-S模拟测试]:序列(构造)

    题目描述 给定$N,A,B$,构造一个长度为$N$的排列,使得:$\bullet$排列长度为$N$:$\bullet$最长上升子序列长度为$A$:$\bullet$最长下降子序列长度为$B$.我们有$ ...

  2. 贪心/构造/DP 杂题选做Ⅱ

    由于换了台电脑,而我的贪心 & 构造能力依然很拉跨,所以决定再开一个坑( 前传: 贪心/构造/DP 杂题选做 u1s1 我预感还有Ⅲ(欸,这不是我在多项式Ⅱ中说过的原话吗) 24. P5912 ...

  3. 贪心/构造/DP 杂题选做Ⅲ

    颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...

  4. Mockito:一个强大的用于Java开发的模拟测试框架

    https://blog.csdn.net/zhoudaxia/article/details/33056093 介绍 本文将介绍模拟测试框架Mockito的一些基础概念, 介绍该框架的优点,讲解应用 ...

  5. Mock 模拟测试简介及 Mockito 使用入门

    Mock 是什么mock 测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法.这个虚拟的对象就是mock对象.mock对象就是真实对象在调试期间的代 ...

  6. springboot2.0入门(四)----mock模拟测试+单元测试

    一.本节主要记录模拟测试.单元测试: 二.mock 测试 1.1什么是Mock? 在面向对象程序设计中,模拟对象(英语:mock object,也译作模仿对象)是以可控的方式模拟真实对象行为的假的对象 ...

  7. csp-s模拟测试99

    csp-s模拟测试99 九九归一直接爆炸. $T1$一眼板子. $T2$一眼语文题(语文的唯一一次$120+$是给模拟出来的可知我的语文能力). $T3$一眼普及题. ?? Hours Later 板 ...

  8. csp-s模拟测试97

    csp-s模拟测试97 猿型毕露.水题一眼秒,火题切不动,还是太菜了. $T1$看了一会儿感觉$woc$期望题$T1??$假的吧??. $T2$秒. $T3$什么玩意儿. 40 01:24:46 00 ...

  9. csp-s模拟测试95

    csp-s模拟测试95 去世场祭. $T1$:这不裸的除法分块吗. $T2$:这不裸的数据结构优化$Dp$吗. $T3$:这不裸的我什么都不会搜索骗$30$分吗. 几分钟后. 这除法分块太劲了..(你 ...

随机推荐

  1. Java ——JDBC数据库编程

    数据库分类 关系型数据库:以表来存放数据的,数据与数据之间的关系通过表之间的连接体现 面向对象的数据库:保存的是对象本身 其它 数据库:数据库管理系统中创建一个个的保存数据的单位 数据是保存在数据库的 ...

  2. Mac015--在Mac下安装使用Vagrant

    网址:http://yansu.org/2014/04/10/install-vagrant-in-mac.html 一.安装Vagrant 下载地址在http://www.vagrantup.com ...

  3. xmake v2.1.5版本新特性介绍

    2.1.5版本现已进入收尾阶段,此版本加入了一大波新特性,目前正在进行稳定性测试和修复,在这里,先来介绍下新版本中引入了哪些新特性和改进. 1. 提供类似cmake的find_*系列接口,实现各种查找 ...

  4. web 前端2 CSS

    CSS CSS是Cascading Style Sheets的简称,中文称为层叠样式表,用来控制网页数据的表现,可以使网页的表现与数据内容分离. 一 css的四种引入方式 1.行内式          ...

  5. vue—两个数组,去重相同项

  6. FastDFS搭建单机图片服务器(二)

    防丢失转载:https://blog.csdn.net/MissEel/article/details/80856194 根据 分布式文件系统 - FastDFS 在 CentOS 下配置安装部署 和 ...

  7. RESUful风格

    1.7 RESTful风格 1.7.1 RESTful风格介绍 RESTful是一种软件架构风格! RESTful架构风格规定,数据的元操作,即CRUD(create, read, update和de ...

  8. $.ajax()方法详解(网上引用)

    jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数,请求方式(p ...

  9. mysql 可重复读

    概念 Repeatable Read(可重复读):即:事务A在读到一条数据之后,此时事务B对该数据进行了修改并提交,那么事务A再读该数据,读到的还是原来的内容. 实现原理(MVCC [ 多版本并发控制 ...

  10. [转载]企业级应用架构(NHibernater+Spring.Net+MVC3)

    本人已经从事公司两套这类架构系统的开发工作啦!对于这套架构,我惊叹不已!BPS和CMS系统都是采用这套架构.但本人也同时渐渐发现了这套架构有诸多 不足之处,于是本人利用闲暇时光进一步改进了这套架构.新 ...