Arc073_F Many Moves
题目大意
有$n$个格子从左到右依次挨着,一开始有两枚棋子分布在$A,B$某一个或两个格子里,有$m$个操作,第$i$次操作要求你把其中一个棋子移到$X_i$上,移动一个棋子的代价是两个格子之间的距离,求移完所有棋子的代价之和的最小值。
题解
首先这题显然不能贪心,后面的要求会对当前的选择产生影响。
考虑朴素的$n^2$的$DP$,设$F_{i,k}$表示满足恰好前$i$个操作时,除了处在$X_i$处的棋子,另一个棋子处在$k$的格子处的代价。
那么转移很显然$F_{i+1,k}=F_{i,k}+|X_i-X_{i+1}|$。
特别的,有另一处转移$F_{i+1,X_i}=\min\{F_{i,j}+|j-X_{i+1}|\}$。
这个第二处转移中绝对值看起来非常碍眼,考虑将按照$j\leq X_i,j\geq X_i$的情况变成了两类。
不难发现
对于$j\leq X_i,F_{i+1,X_i}=\min\{F_{i,j}+X_{i+1}-j\}$
对于$j\geq X_i,F_{i+1,X_i}=\min\{F_{i,j}+j-X_{i+1}\}$
考虑用线段树维护$F_{i,j}-j,F_{i,j}+j$,每次第一处转移相当于全局加,第二种转移相当于取一个前缀或后缀的最小值,然后转移就是单点取$min$。
初始时,令$X_0=B,F_{0,A}=0$其余的$F=INF$,每次转移,每个点取$min$即可。
复杂度$O(m\log n)$。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define M 200020
#define INF 10000000000000ll
using namespace std;
namespace IO{
const int BS=(1<<20); char Buffer[BS],*HD,*TL;
char Getchar(){if(HD==TL){TL=(HD=Buffer)+fread(Buffer,1,BS,stdin);} return (HD==TL)?EOF:*HD++;}
int read(){
int nm=0,fh=1; char cw=Getchar();
for(;!isdigit(cw);cw=Getchar()) if(cw=='-') fh=-fh;
for(;isdigit(cw);cw=Getchar()) nm=nm*10+(cw-'0');
return nm*fh;
}
}
using namespace IO;
int n,m,A,B,G[M]; LL maxn,p[M<<2][2],ans=INF;
void pushup(int x){
p[x][0]=min(p[x<<1][0],p[x<<1|1][0]);
p[x][1]=min(p[x<<1][1],p[x<<1|1][1]);
}
void build(int x,int l,int r){
if(l==r){
if(l==A) p[x][0]=-l,p[x][1]=l;
else p[x][0]=p[x][1]=INF; return;
}
int mid=((l+r)>>1); build(x<<1,l,mid);
build(x<<1|1,mid+1,r),pushup(x);
}
LL qry(int x,int l,int r,int L,int R,int kd){
if(r<L||R<l) return INF; if(L<=l&&r<=R) return p[x][kd];
int mid=((l+r)>>1); return min(qry(x<<1,l,mid,L,R,kd),qry(x<<1|1,mid+1,r,L,R,kd));
}
void mdf(int x,int l,int r,int pos,LL dt){
if(l==r){p[x][0]=min(p[x][0],dt-l),p[x][1]=min(p[x][1],dt+l);return;}
int mid=((l+r)>>1);if(pos<=mid) mdf(x<<1,l,mid,pos,dt);else mdf(x<<1|1,mid+1,r,pos,dt); pushup(x);
}
void dfs(int x,int l,int r){
if(l==r){ans=min(ans,p[x][0]+(LL)l);return;}
int mid=((l+r)>>1);dfs(x<<1,l,mid),dfs(x<<1|1,mid+1,r);
}
int main(){
n=read(),m=read(),A=read(),B=read(),G[0]=B,build(1,1,n);
for(int i=1;i<=m;i++){
G[i]=read(); LL t1=G[i]+qry(1,1,n,1,G[i],0)+maxn;
LL t2=qry(1,1,n,G[i],n,1)-G[i]+maxn,dt=abs(G[i]-G[i-1]);
maxn+=dt,mdf(1,1,n,G[i-1],min(t1,t2)-maxn);
} dfs(1,1,n),printf("%lld\n",maxn+ans); return 0;
}
Arc073_F Many Moves的更多相关文章
- [LeetCode] Minimum Moves to Equal Array Elements II 最少移动次数使数组元素相等之二
Given a non-empty integer array, find the minimum number of moves required to make all array element ...
- [LeetCode] Minimum Moves to Equal Array Elements 最少移动次数使数组元素相等
Given a non-empty integer array of size n, find the minimum number of moves required to make all arr ...
- LeetCode Minimum Moves to Equal Array Elements II
原题链接在这里:https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/ 题目: Given a non-empt ...
- LeetCode Minimum Moves to Equal Array Elements
原题链接在这里:https://leetcode.com/problems/minimum-moves-to-equal-array-elements/ 题目: Given a non-empty i ...
- LeetCode 453 Minimum Moves to Equal Array Elements
Problem: Given a non-empty integer array of size n, find the minimum number of moves required to mak ...
- Knight Moves
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...
- HDU 1372 Knight Moves
最近在学习广搜 这道题同样是一道简单广搜题=0= 题意:(百度复制粘贴0.0) 题意:给出骑士的骑士位置和目标位置,计算骑士要走多少步 思路:首先要做这道题必须要理解国际象棋中骑士的走法,国际象棋中 ...
- [宽度优先搜索] HDU 1372 Knight Moves
Knight Moves Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tot ...
- HDU 1372 Knight Moves (bfs)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1372 Knight Moves Time Limit: 2000/1000 MS (Java/Othe ...
随机推荐
- CSS3 - 鼠标移入移出时改变样式
1,使用伪类实现样式切换伪类是CSS2.1时出现的新特性,让许多原本需要JavaScript才能做出来的效果使用CSS就能实现.比如实现下面的鼠标悬停效果,只要为:hover伪类应用一组新样式即可.当 ...
- MFC添加菜单资源与菜单执行函数的两种命令形式
添加资源->新建一个菜单资源->选择相应的对话框 菜单的执行函数命令形式: COMMAD 是指点击菜单后的执行命令 UPDATE_COMMAND_UI 是指点击菜单后菜单状态的函数
- nginx 基础配置详解
#本文只对nginx的最基本配置项做一些解释,对于配置文件拆分管理,更详细的集群健康检查的几种方式,检查策略等在此不做详细解释了. #运行用户user nobody;#启动进程,通常设置成和cpu的数 ...
- Android系统移植与调试之------->如何修改Android设备的桌面背景图片
1.切换到~/mx0831-0525/device/other/TBDG1073/overlay/frameworks/base/core/res/res目录 2.准备好一张相应尺寸的图片并且命名为d ...
- 我的Android进阶之旅------>Android中android:visibility 属性VISIBLE、INVISIBLE、GONE的区别
在Android开发中,大部分控件都有visibility这个属性,其属性有3个分别为"visible "."invisible"."gone&quo ...
- 10.Django数据库操作(增删改)
插入数据 命令:create 或者 save create用法:ModelName.objects.create(itemName="itemValue") save用法:mode ...
- 关于highcharts-ng
1.内容都正确但是不显示,使用parseInt()方法转换
- Python赋值魔法技巧
实验环境: [root@localhost ~]# python -V Python 2.7.5 1.序列解包 多个赋值操作可以同时进行 >>> x,y,z = 1,2,3 > ...
- 中国移动OnetNet云平台 GET指令使用
GET /devices//datastreams/KEY HTTP/1.1 Host: api.heclouds.com api-key: pmWLtnkDBSreKfvg7GsClUXdXa4A ...
- 内存写越界导致破环堆结构引起的崩溃问题定位经验[如报错malloc(): memory corruption或free(): invalid next size]
前段时间开发的一个后端C模块上线后,线上出core,初始时,因为訪问压力不大,所以崩溃是上线3天左右出现的.当时用gdb跟进调用堆栈并检查源代码,发现出core位置的代码沒有啥问题.因为当时开发任务较 ...