题目大意:有$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;
}

  

转载于:https://www.cnblogs.com/Memory-of-winter/p/9466135.html

[AT2558]Many Moves相关推荐

  1. [Educational Codeforces Round 16]A. King Moves

    [Educational Codeforces Round 16]A. King Moves 试题描述 The only king stands on the standard chess board ...

  2. poj - 2243 Knight Moves

    这题和poj 1915一样,用bfs做走马步.现在再看当时的代码,真是好幼稚啊. 1 #include <stdio.h> 2 #include <string.h> 3 in ...

  3. 1 Knight Moves

    Problem F- Knight Moves 题目来源:https://vjudge.net/contest/207868#problem/F Problem description: 题意概括:中 ...

  4. LeetCode Minimum Moves to Equal Array Elements II

    原题链接在这里:https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/ 题目: Given a non-empt ...

  5. java求最小步数,使数组值相等的最小步数 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 ...

  6. ubuntu16安装pylearn2 出现错误提示importerror:no module named six.moves

    由于市面上的一些教程时间比较早,入门学习时跟随教程安装容易出现各种错误,这些错误基本都是版本不同导致的 所以,我们安装过程中一定要指出包的版本,如果你已经遇到no module named six.m ...

  7. HDU 1372 Knight Moves

    最近在学习广搜  这道题同样是一道简单广搜题=0= 题意:(百度复制粘贴0.0) 题意:给出骑士的骑士位置和目标位置,计算骑士要走多少步 思路:首先要做这道题必须要理解国际象棋中骑士的走法,国际象棋中 ...

  8. leetcode 453,462. Minimum Moves to Equal Array Elements I, II | 453, 462. 最少移动次数使数组元素相等(图解)

    453. Minimum Moves to Equal Array Elements https://leetcode.com/problems/minimum-moves-to-equal-arra ...

  9. OpenJudge/Poj 1915 Knight Moves

    1.链接地址: http://bailian.openjudge.cn/practice/1915 http://poj.org/problem?id=1915 2.题目: 总Time Limit: ...

最新文章

  1. 随想_8_Windows_XP_Explorer_错误
  2. mac 下如何使用lrzsz 上传下载文件
  3. 报表-对于多数据进行 分sheet以及 分workbook处理
  4. 论文辅助笔记(代码实现):Bayesian Probabilistic Matrix Factorizationusing Markov Chain Monte Carlo
  5. Integer的cache缓存问题
  6. 史上最强Dubbo面试28题答案详解:核心功能+服务治理+架构设计等
  7. docker开放的端口_docker-5-解决宿主机没有开放81端口却可以直接访问docker启动的81端口nginx容器的问题...
  8. 可视化数据展示工具ChatSQL
  9. 1061 判断题 (15 分)—PAT (Basic Level) Practice (中文)
  10. 基于python 爬虫_基于python的爬虫(一)
  11. 51单片机课程设计数显简易频率计设计
  12. 如何下载行政区划地图
  13. 图片中添加箭头【使用PPT实现】
  14. java.lang.abstractmethoderror
  15. Ubuntu的一些高(sao)效(cao)率(zuo)工具
  16. Ringbuffer 范例
  17. 计算机中pdf怎么预览,如何在浏览器中开启PDF时默认显示Adobe Reader XI工具栏
  18. Mac 强制退出应用程序的办法
  19. 细胞培养常见问题分析
  20. 基于matlab的光学薄膜特性分析,基于matlab的光学薄膜特性分析.doc

热门文章

  1. map转成url拼接请求参数
  2. @Scheduled定时任务不生效的原因
  3. GeoTools使用之JTSFactoryFinder接口
  4. ES启动错误 ERROR: the system property [es.path.conf] must be set
  5. linux下kafka安装与配置
  6. linux非编工作站,高清EDIUS非编网络系统建设 在线非编系统
  7. java spark yarn_《Spark官方文档》在YARN上运行Spark
  8. [猜你喜欢]冠军 yes,boy! 分享 | 推荐系统也可以很简单 做个记录 以后方便学习
  9. [python机器学习及实践(2)]Sklearn实现朴素贝叶斯
  10. Ocata:Packstack Ocata does not configure nova for placement API