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 ...
随机推荐
- win10中如何成功安装lxml
lxml官网地址:http://lxml.de/index.html 问题: 在学习lxm的时候,发现在win10下总是安装失败,如下: 在网上搜索了半天也没找到具体的解决方案,就FQgoogle下, ...
- Android设备各种使用尺寸整理
// 获取屏幕的宽度.高度 Display defDip = getWindowManager().getDefaultDisplay(); int disWidth = defDip.getWidt ...
- Boxes and Candies(贪心)
Boxes and Candies Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement Ther ...
- java高级主题
1 java.util.concurrent.locks.LockSupport park:阻塞线程. unpark:解除阻塞线程. 线程阻塞最基础的组件. 2 sun.misc.Unsafe 可以用 ...
- debian dhcp配置
1 将/etc/network/interfaces中设置成dhcp auto eth0iface eth0 inet dhcp 2 重启网络服务 /etc/init.d/networking res ...
- Data Decisions: DSP vs. DMP
http://www.cmo.com/features/articles/2016/3/9/data-decisions-dsp-vs-dmp.html As marketers assess the ...
- vue前戏ES6
es6语法 es6语法:let和const: { var a=123; let b=234; } console.log(a); console.log(b); 浏览器里会只看到123; 而且还会抱一 ...
- isinstance/issubclass/type的区别?
type() 判断某个对象是否是该类创建的,只看一层,如果是继承类,也不会考虑继承类的类型.. Issubclass() 判断该类是否是另一个类的派生类,也就是子类,参数为类. isinstance( ...
- centos install docker setup centos7 安装docker
centos7 安装docker 1: 安装必要的一些系统工具sudo yum install -y yum-utils device-mapper-persistent-data lvm2 2: 添 ...
- IaaS,PaaS,Saas 云服务的介绍
云服务只是一个统称,可以分成三大类. IaaS:基础设施服务,Infrastructure-as-a-service PaaS:平台服务,Platform-as-a-service SaaS:软件服务 ...