【LOJ3156】「NOI2019」回家路线
【题目链接】
【题目概括】
现在有\(n\)个站点,\(m\)条火车路线,每一条货车路线都有一个起点站点、终点站点、开始时间和到站时间。
对于一直在起点\(1\)的人,终点是\(n\)号点。
如果这个人在站点等待了\(T\)时间,那么他的烦躁值会增加\(A^2\times T+B\times T+C\)。
如果他在\(z\)时刻到达了终点,那么还会增加\(z\)的烦躁值。
请你计算出最小化的烦躁值。
【思路要点】
- 定义状态\(f[i]\)表示乘坐了第\(i\)条火车路线后会有的最小烦躁值。
- 那么状态转移方程为
- \(f[i]=Min(f[j]+A\times(p[i]-q[j])^2+B\times(p[i]-q[j])+C) \ (x[i]=y[j],q[j]\leq p[i])\)
- 转化成斜率式后得到下式,满足决策单调性,用斜率优化就可以解决了。
- \((f[j]+A\times q[j]^2-B\times q[j])_y=(2\times A\times p[i])_k\times (q[j])_x+(f[i]-A\times p[i]^2-B\times p[i])_b\)
- 考虑实现这个\(DP\)。
- 我们考虑按照时间\(DP\)。
- 将一个火车路线拆分成两个事件:火车在\(p_i\)时刻出站和火车在\(q_i\)进站。
- 每一次转移我们将\(DP\)值插入到当前的站点,每一次取斜率最优的。
- 时间复杂度 \(O(MlogM)\)
【代码】
#include <cstdio>
#include <algorithm>
#include <vector>
#define INF 0x3f3f3f3f3f3f3f3f
typedef long long ll;
template <typename T> void chkmin(T& x, T y) {
x = std::min(x, y);
}
const int N = 1e5 + 5;
const int M = 2e5 + 5;
const int NT = 1e3 + 5;
int n, m, A, B, C;
int x[M], y[M], p[M], q[M];
ll dp[M];
std::vector<int> S[NT];
int head[N];
ll ans;
ll Y(int i) {
return dp[i] + A * q[i] * q[i] - B * q[i];
}
ll X(int i) {
return q[i];
}
struct Node {
ll x, y;
int id;
Node(int Id = 0) {
x = X(Id), y = Y(Id);
id = Id;
}
};
std::vector<Node> que[N];
std::vector<int> fin[NT];
bool cmp1(Node a, Node b, ll k) {
return (b.y - a.y) > k * (b.x - a.x);
}
bool cmp2(Node a, Node b, Node c, Node d) {
return ((b.y - a.y) * (d.x - c.x)) > ((d.y - c.y) * (b.x - a.x));
}
ll F(ll x) {
return A * x * x + B * x + C;
}
void add(int id) {
Node now = Node(id);
int pos = y[id];
while ((int) que[pos].size() - head[pos] >= 2) {
if (cmp2(que[pos][que[pos].size() - 2], now, que[pos][que[pos].size() - 2], que[pos][que[pos].size() - 1])) break;
que[pos].pop_back();
}
que[pos].push_back(now);
}
void del(int id, ll k) {
while ((int) que[id].size() - head[id] >= 2) {
if (cmp1(que[id][head[id]], que[id][head[id] + 1], k)) break;
head[id]++;
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("route.in", "r", stdin);
freopen("route.out", "w", stdout);
#endif
scanf("%d %d %d %d %d", &n, &m, &A, &B, &C);
for (int i = 1; i <= m; i++) {
scanf("%d %d %d %d", &x[i], &y[i], &p[i], &q[i]);
S[p[i]].push_back(i);
}
que[1].push_back(Node(0));
ans = INF;
for (int T = 0; T <= 1000; T++) {
for (int i = 0; i < (int) fin[T].size(); i++) {
add(fin[T][i]);
}
fin[T].clear();
for (int i = 0; i < (int) S[T].size(); i++) {
int routeId = S[T][i], st = x[routeId];
if ((int) que[st].size() <= head[st]) continue;
del(st, 2 * A * p[routeId]);
int j = que[st][head[st]].id;
dp[routeId] = dp[j] + F(p[routeId] - q[j]);
if (y[routeId] == n) chkmin(ans, dp[routeId] + q[routeId]);
fin[q[routeId]].push_back(routeId);
}
}
printf("%lld\n", ans);
return 0;
}
【LOJ3156】「NOI2019」回家路线的更多相关文章
- LOJ 3156: 「NOI2019」回家路线
题目传送门:LOJ #3156. 题意简述: 有一张 \(n\) 个点 \(m\) 条边的有向图,边有两个权值 \(p_i\) 和 \(q_i\)(\(p_i<q_i\))表示若 \(p_i\) ...
- loj3161「NOI2019」I 君的探险(随机化,整体二分)
loj3161「NOI2019」I 君的探险(随机化,整体二分) loj Luogu 题解时间 对于 $ N \le 500 $ 的点,毫无疑问可以直接 $ O(n^2) $ 暴力询问解决. 考虑看起 ...
- 【LOJ】#2068. 「SDOI2016」探险路线
题解 少考虑了情况,导致我以为是暴力讨论一次角落移动 de了两天才反应过来--简直降智 事实上,我们把移动分三类,一种是在边界跳过一段,一种是在左上角上左上左上左这样撞墙,在右下角下右下右下右这么撞墙 ...
- LOJ 3158: 「NOI2019」序列
题目传送门:LOJ #3158. 题意简述: 给定两个长度为 \(n\) 的正整数序列 \(a,b\),要求在每个序列中都选中 \(K\) 个下标,并且要保证同时在两个序列中都被选中的下标至少有 \( ...
- LOJ 3160: 「NOI2019」斗主地
题目传送门:LOJ #3160. 简要题意: 有一个长度为 \(n\) 的序列 \(a\),初始时 \(a_i=i\) 或 \(a_i=i^2\),这取决于 \(\mathrm{type}\) 的值. ...
- LOJ 3159: 「NOI2019」弹跳
题目传送门:LOJ #3159. 题意简述: 二维平面上有 \(n\) 个整点,给定每个整点的坐标 \((x_i,y_i)\). 有 \(m\) 种边,第 \(i\) 种边从 \(p_i\) 号点连向 ...
- 「NOI2019」弹跳(KD树)
题意:w×h网格中有n个点,m条边.每条边可以从p点花费t时间到一个矩形中的任意点,求1号点到每个点的最少时间. \(1<=w,h<=n<=70000,1<=m<=150 ...
- @loj - 3157@「NOI2019」机器人
目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 R 喜欢研究机器人. 最近,小 R 新研制出了两种机器人,分 ...
- 「NOI2019」序列
NKOJ卡常卡不过QAQ description 给两个A,B序列,让你分别在A,B中各选k个数,其中至少有L对下标相等. Solution 把问题转化为至多选n-K对下标不同的对. 配对问题就用费用 ...
随机推荐
- 不同浏览器之间的javascript和css兼容性问题
po主手头维护的网站是上世纪的作品.当时约摸ie所占的市场份额相当大,以至于开发人员都没有考虑到浏览器兼容性问题(这不科学!).怎奈po主是个强迫症阿.最近在修改的时候,还是没忍住,把兼容性问题解决了 ...
- celery异步发送邮件
利用Django框架发送邮件的详细过程,在前两天的博客中有所记录,但是单纯的那样发邮件是有非常大的问题的,这就需要celery异步发送来解决 首先我们来看一下邮件发送的过程: Django网站先发送到 ...
- Codeforces 1178D. Prime Graph
传送门 首先每个点至少要有两条边连接 那么容易想到先保证这一点然后再慢慢加边 那么先构成一个环即可:$(1,2),(2,3),(3,4)...(n,1)$ 然后考虑加边,发现一个点加一条边还是合法的, ...
- STM32F10xxx_启动模式
目录 STM32F10xxx_启动模式 更新记录 启动配置 参考: STM32F10xxx_启动模式 更新记录 version status description date author V1.0 ...
- 《HTML、CSS、Javascript网页制作,从入门到精通》——第一章 HTML基础,第二章HTML基本标记
1)HTML的基本概念 HTML就一种描述性的标记语言,是文档的超文本标记语言. 基本结构为: HTML标记组成 : <标记元素> 源文件中标记是不区分大小写的. 2)编写方法: 1&g ...
- vue项目-axios封装、easy-mock使用
vue全家桶概括下来就是 项目构建工具(vue-cli) 路由(vue-router) 状态管理(vuex) http请求工具 vue有自己的http请求工具插件vue-resource,但是vue2 ...
- 打印canvas
这里我是新开窗口打印,会存在一个问题:就是不关闭打印窗口回到父页面,父页面不响应的情况 所以,我另外写了一个监听离开新开窗口,弹窗提示的函数,提示用户关闭打印窗口,方可进行后续操作 额,发现问题更大了 ...
- Js实现图片点击切换与轮播
Js实现图片点击切换与轮播 图片点击切换 <!DOCTYPE html> <html> <head> <meta charset="UTF-8&qu ...
- RE 逆向工程初学者指南:方法和工具
简评: RE 两种分析,静态.动态.好好分析静态因为能够解决 70 % 的问题.介绍了一些工具和方法.Enjoy yourself. 最近几天,我决定试水逆向工程,即使在计算机和编程相关领域有一定的基 ...
- java8学习之Collector复合与注意事项
接着上一次[http://www.cnblogs.com/webor2006/p/8318066.html]继续对Collector进行javadoc详读,上一次读到了这: 接下来一条条来过目一下: ...