传送门

看一眼感觉就是 $dp$,但是似乎状态太多了

考虑推推性质

首先每到一行都要把所有宝藏都走到,那么一定会走到最左边的和最右边的宝藏

注意到一旦走完所有宝藏时肯定是在最左边或者最右边的宝藏位置

并且此时要往上走,显然是选择左边或右边的最近的路上去,因为如果选择更远的路上去还不如先上去再走到更远的那个位置

所以发现,我们每一层上去只有四种选择:最左边宝藏的左右两个最近的上去,最右边宝藏的左右两个最近的上去

直接预处理一下每一层的这四个位置然后标号 $0,1,2,3$

那么就可以安心 $dp$ 了,直接设 $f[i][4]$ 表示到了第 $i$ 层并把第 $i$ 层的宝藏走完,此时准备到更上一层的位置为第 $0/1/2/3$

把一层走完直接按先到最左边或者先到最右边分类讨论一下即可

要注意我们一旦把最高的存在宝藏的一层走完即可结束,并且不用准备到更上一层,所以最后一层的转移到特殊处理一下

细节挺多的要仔细点

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=4e5+;
const ll INF=1e18;
ll n,m,K,Q,b[N],L[N],R[N];
ll pre[N],nxt[N],pos[N][];
ll f[N][];
inline ll calc(ll s,ll t,int i)
{
if(s<||s>m||t<||t>m) return INF;//
if(!R[i]) return abs(s-t);//
return min( abs(s-L[i])+abs(L[i]-R[i])+abs(R[i]-t) , abs(s-R[i])+abs(L[i]-R[i])+abs(L[i]-t) );
}
int main()
{
n=read(),m=read(),K=read(),Q=read();
ll x,y; memset(L,0x3f,sizeof(L));
for(int i=;i<=K;i++)
{
x=read(),y=read();
L[x]=min(L[x],y); R[x]=max(R[x],y);
}
for(int i=;i<=Q;i++) b[i]=read();
int l=,r=; sort(b+,b+Q+); b[Q+]=m+;
for(int i=;i<=m;i++)
{
while(b[l+]<=i) l++;
while(b[r]<i) r++;
pre[i]=b[l]; nxt[i]=b[r];
}
for(int i=;i<=n;i++)
{
if(L[i]<=m) pos[i][]=pre[L[i]],pos[i][]=nxt[L[i]];
if(R[i]>=) pos[i][]=pre[R[i]],pos[i][]=nxt[R[i]];
}
memset(f,0x3f,sizeof(f));
int pre=,prre=;
for(int i=;i<;i++)
if(R[pre]) f[pre][i]=calc(,pos[pre][i],pre);
else f[pre][i]=nxt[]-,pos[pre][i]=nxt[];//
for(int i=pre+;i<=n;i++)
{
if(!R[i]) continue;
for(int j=;j<;j++)
for(int k=;k<;k++)
f[i][j]=min(f[i][j],f[pre][k]+calc(pos[pre][k],pos[i][j],i)+(i-pre));
prre=pre; pre=i;
}
ll Ans=INF;
if(!prre) { printf("%lld\n",R[pre]-); return ; }//
for(int k=;k<;k++)
Ans=min(Ans, f[prre][k]+(pre-prre)+ min(abs(pos[prre][k]-L[pre]),abs(pos[prre][k]-R[pre])) +(R[pre]-L[pre]) );//
printf("%lld\n",Ans);
return ;
}

最新文章

  1. MySQL Replication需要注意的问题
  2. Mac系统默认MAWP配置
  3. 管理批量邮箱 FOXMAIL 和网易闪电邮(PC端)有什么区别? 对比
  4. 30-Razor语法基础
  5. 从零开始学android开发-获取控件
  6. 配置tomcat连接器后,启动服务报错“No Certificate file specified or invalid file format&quot;异常
  7. JS当前日期相加相减
  8. C 语言 printf格式控制详解
  9. iBatis 的条件查询
  10. javascript算法挑战
  11. codeblocks修改字体颜色-背景颜色
  12. layabox typescript 安装固定版本
  13. 跟随我在oracle学习php(1)
  14. RESTful API 设计指南,RESTful API 设计最佳实践
  15. .net webapi 收不到json 实体类参数,返回的json中带有k__BackingField
  16. 给VMware下的Linux扩容磁盘空间到根分区(以centos7.0为例)
  17. native.js 判断是否安装某app
  18. Nginx 功能
  19. HashMap底层实现原理以及HashMap与HashTable区别以及HashMap与HashSet区别
  20. 爬虫实战:汽车之家配置页面 破解伪元素和混淆JS

热门文章

  1. js获取当前页面url信息
  2. 2.微服务开发框架——Spring Cloud
  3. mysql基础知识语法汇总整理(一)
  4. Linux TC限制流量
  5. 精讲JS逻辑运算符&amp;&amp;、||,位运算符|,&amp;
  6. Creator性能优化
  7. ambari部署Hadoop集群(1)
  8. LC 711. Number of Distinct Islands II
  9. javascript之BOM对象总结
  10. url protocol