[AT2558]Many Moves
题目大意:有$n$个位置$1,2,\dots n$;你有两个棋子$A$和$B$,你要进行$q$次操作,第$i$次操作给定一个$x_i$,你要选择一个棋子移动到$x_i$;求两个棋子最小移动的步数之和。
题解:一个$O(n^2)$的$DP$容易想到$f_{i,j}$表示到了第$i$步,另一个棋子在$j$这个位置。
$$f_{i,x_{i-1}}=\min\{f_{i-1,j}+|x_i-j|\}$$
$$f_{i,j}=f_{i-1,j}+|x_i-x_{i-1}|$$
下面一个还好做,可上面一个呢?
可以考虑拆成$j\leq x_i$和$j>x_i$来做
$$\therefore f_{i,x_{i-1}} =
\begin{cases}
f_{i-1,j}+x_i-j\quad(j\leq x_i)\\
f_{i-1,j}+j-x_i\quad(j>x_i)
\end{cases}$$
然后发现是区间修改求最小值,可以用线段树来做。
卡点:1.转移时把$x_{i-1}$写成了$x_{i}$
C++ Code:
#include <cstdio>
#include <cstring>
#define maxn 200010
using namespace std;
const long long inf = 0x3f3f3f3f3f3f3f3f;
inline long long min(long long a, long long b) {return a < b ? a : b;}
inline long long abs(long long a) {return a > 0 ? a : -a;}
int n, k, x, y;
int q, last;
long long V[maxn << 2][3], cov[maxn << 2];
void pushdown(int rt) {
int lc = rt << 1, rc = rt << 1 | 1;
long long &tmp = cov[rt];
V[lc][0] += tmp;
V[lc][1] += tmp;
V[lc][2] += tmp;
cov[lc] += tmp;
V[rc][0] += tmp;
V[rc][1] += tmp;
V[rc][2] += tmp;
cov[rc] += tmp;
tmp = 0;
}
void update(int rt) {
int lc = rt << 1, rc = rt << 1 | 1;
V[rt][0] = min(V[lc][0], V[rc][0]);
V[rt][1] = min(V[lc][1], V[rc][1]);
V[rt][2] = min(V[lc][2], V[rc][2]);
}
void add(int rt, int l, int r, int p, long long num) {
if (l == r) {
V[rt][0] = num;
V[rt][1] = num + l;
V[rt][2] = num - l;
return ;
}
if (cov[rt]) pushdown(rt);
int mid = l + r >> 1;
if (p <= mid) add(rt << 1, l, mid, p, num);
else add(rt << 1 | 1, mid + 1, r, p, num);
update(rt);
}
void add(long long num, int rt = 1) {
V[rt][0] += num;
V[rt][1] += num;
V[rt][2] += num;
cov[rt] += num;
}
long long ask(int rt, int l, int r, int L, int R, int op) {
if (L <= l && R >= r) return V[rt][op];
pushdown(rt);
int mid = l + r >> 1;
long long ans = inf;
if (L <= mid) ans = ask(rt << 1, l, mid, L, R, op);
if (R > mid) ans = min(ans, ask(rt << 1 | 1, mid + 1, r, L, R, op));
return ans;
}
int main() {
scanf("%d%d%d%d", &n, &k, &x, &y);
scanf("%d", &q);
memset(V, 0x3f, sizeof V);
add(1, 1, n, x, abs(y - q));
add(1, 1, n, y, abs(x - q));
while (--k) {
last = q; scanf("%d", &q);
long long t0 = ask(1, 1, n, last, last, 0) + abs(q - last);
long long t1 = ask(1, 1, n, q, n, 1) - q;
long long t2 = ask(1, 1, n, 1, q, 2) + q;
long long ans = min(t0, min(t1, t2));
add(abs(q - last));
add(1, 1, n, last, ans);
}
printf("%lld\n", V[1][0]);
return 0;
}
[AT2558]Many Moves的更多相关文章
- AT2558 [ARC073D] Many Moves
开始被标签带骗了. 考虑一个\(dp\),\(f[i][j]\)代表有一个棋子在\(x_i\),另外一个\(j\)的最小答案. 那么考虑转移. 如果\(j != x_{i - 1}\) 那么答案自然贡 ...
- [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 ...
随机推荐
- jquer搜索
<body> <br/> <center> <tr><td>创建时间:</td><td><input type ...
- python 函数 练习
# 2.写函数,接收n个数字,求这些参数数字的和. def sum_func(*args): total = 0 for i in args: total += i return total prin ...
- C语言学习记录_2019.01.29
C语言的灵魂:指针 #include <stdio.h> int main(int argc, char **argv) { printf("Hello, World!\n&q ...
- codeblocks编译出错问题的解答!(编译c++ 或者c程序)
典型错误:https://blog.csdn.net/jingmiaa/article/details/52054204 MinGW下载并配置gcc/g++编译环境:https://blog.csdn ...
- C++11中decltype的使用
The decltype type specifier yields the type of a specified expression. The decltype type specifier, ...
- MySQL server has gone away 错误处理
解决方案1: 这个是mysql自身的一个机制: mysql连接的空闲时间超过8小时后 MySQL自动断开该连接解决办法有两个: 1.修改mysql 配置 增 ...
- abo dto属性验证的坑
问题回现: public class ShipmentRequestDto { public string FromPhoneNumber { get; set; } /// <summary& ...
- K8s集群内热改代码
1.登录到k8s master服务器 $ ssh developer@XXX.XXX.X.XXX(IP地址) 2.查看服务容器所在的节点(以xx-server为例) $ kubectl get pod ...
- QC的使用学习(一)
今天学习的时间很少,就利用睡前的一点时间来学习一下刚安装好的QC. 1.后台站点管理.主要是对八大选项的了解: site project:顾名思义,就站点项目管理,管理域和项目. site user: ...
- 数据结构(python语言)目录链接
第一章 准备工作 课时0:0.数据结构(python语言) 基本概念 算法的代价及度量!!!