LOJ 3156: 「NOI2019」回家路线
题目传送门:LOJ #3156。
题意简述:
有一张 \(n\) 个点 \(m\) 条边的有向图,边有两个权值 \(p_i\) 和 \(q_i\)(\(p_i<q_i\))表示若 \(p_i\) 时刻在这条边的起点,则 \(q_i\) 时刻能到达这条边的终点。
你需要规划一条路线,使得从起点 \(1\) 号点出发,沿着这条路线到达终点 \(n\) 号点。
假设路线依次经过的边为 \(\{a_1,a_2,\ldots,a_k\}\),则需要保证 \(q_{a_{i-1}}\le p_{a_i}\)。
而这条路线的代价是 \(\displaystyle q_{a_k}+\sum_{i=2}^{k}f(p_{a_i}-q_{a_{i-1}})+f(p_{a_1})\),其中 \(f(x)=\mathrm{A}x^2+\mathrm{B}x+\mathrm{C}\)。
你需要使得你规划的路径的代价最小,输出这个最小代价。
题解:
转移之间的代价是一个二次函数,这是显然的斜率优化 DP 模型。
考虑 \(\mathrm{f}[i]\) 表示经过第 \(i\) 条边后的 \(\sum f(p_{a_j}-q_{a_{j-1}})\),化简式子:
\]
其中斜率的表达式是显然的,\(x\) 坐标是 \(q_i\),\(y\) 坐标是 \(\mathrm{f}[i]+\mathrm{A}q_i^2-\mathrm{B}q_i\),令 \(\mathrm{D}_i=\mathrm{A}p_i^2+\mathrm{B}p_i+\mathrm{C}\),
则 \(\displaystyle\mathrm{f}[i]=\mathrm{D}_i+\min_{y_j=x_i,q_j\le p_i}\{y_j-2\mathrm{A}p_ix_j\}\)。
考察两个合法转移点 \(j\) 和 \(k\)(\(x_j<x_k\)),转移点 \(j\) 比转移点 \(k\) 优当且仅当:
\]
因为不等号是大于号,所以维护下凸壳。
注意,为了方便,更新顺序为按照 \(p_i\) 从小到大,这样右侧斜率是递增的,但是并不能更新完立刻加入凸壳,而是应该等到轮到相应的 \(p_i\) 时再加入。
以下是代码,时间复杂度为 \(\mathcal{O}(n+m+\max q)\):
#include <cstdio>
#include <algorithm>
#include <vector>
typedef double db;
const int MN = 100005, MM = 200005, MQ = 1005;
int N, M, _A, _B, _C, Ans = 0x3f3f3f3f;
int d[MN], eu[MM], ev[MM], ep[MM], eq[MM];
std::vector<int> vp[MQ], vq[MQ];
int X[MM], Y[MM], f[MM];
int _stk[MM], *stk[MN], _l[MN], _r[MN];
inline db Slope(int i, int j) {
if (X[i] == X[j]) return Y[i] == Y[j] ? 0 : Y[i] < Y[j] ? 1e99 : -1e99;
return (db)(Y[j] - Y[i]) / (X[j] - X[i]);
}
int main() {
freopen("route.in", "r", stdin);
freopen("route.out", "w", stdout);
scanf("%d%d%d%d%d", &N, &M, &_A, &_B, &_C);
ev[0] = 1, vq[0].push_back(0), ++d[1];
for (int i = 1; i <= M; ++i) {
scanf("%d%d%d%d", &eu[i], &ev[i], &ep[i], &eq[i]);
vp[ep[i]].push_back(i);
vq[eq[i]].push_back(i);
++d[ev[i]];
}
stk[0] = _stk;
for (int i = 1; i <= N; ++i) stk[i] = stk[i - 1] + d[i - 1], _l[i] = 1;
for (int t = 0; t <= 1000; ++t) {
for (auto i : vq[t]) {
int u = ev[i], *st = stk[u], l = _l[u], &r = _r[u];
while (l < r && Slope(st[r - 1], st[r]) > Slope(st[r], i)) --r;
st[++r] = i;
if (u == N && Ans > f[i] + eq[i]) Ans = f[i] + eq[i];
}
for (auto i : vp[t]) {
int u = eu[i], *st = stk[u], &l = _l[u], r = _r[u];
while (l < r && Slope(st[l], st[l + 1]) < 2 * _A * t) ++l;
if (l <= r) f[i] = Y[st[l]] - 2 * _A * t * X[st[l]] + _A * t * t + _B * t + _C;
else f[i] = 0x3f3f3f3f;
X[i] = eq[i], Y[i] = f[i] + _A * eq[i] * eq[i] - _B * eq[i];
}
}
printf("%d\n", Ans);
return 0;
}
LOJ 3156: 「NOI2019」回家路线的更多相关文章
- 【LOJ3156】「NOI2019」回家路线
[题目链接] [点击打开链接] [题目概括] 现在有\(n\)个站点,\(m\)条火车路线,每一条货车路线都有一个起点站点.终点站点.开始时间和到站时间. 对于一直在起点\(1\)的人,终点是\(n\ ...
- 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\) 号点连向 ...
- @loj - 3157@「NOI2019」机器人
目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 R 喜欢研究机器人. 最近,小 R 新研制出了两种机器人,分 ...
- loj3161「NOI2019」I 君的探险(随机化,整体二分)
loj3161「NOI2019」I 君的探险(随机化,整体二分) loj Luogu 题解时间 对于 $ N \le 500 $ 的点,毫无疑问可以直接 $ O(n^2) $ 暴力询问解决. 考虑看起 ...
- Loj #2192. 「SHOI2014」概率充电器
Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...
- Loj #3096. 「SNOI2019」数论
Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...
- Loj #3093. 「BJOI2019」光线
Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...
随机推荐
- Bootstrap-table 单元格合并 、表头合并
1.页面引入js/css @*1.Jquery组件引用*@ <script src="~/Scripts/jquery-1.10.2.js"></script&g ...
- WPF 目录树绑定 与 遍历
定义树节点,(编译环境VS2017) public class GBTreeNode : INotifyPropertyChanged { private string _deviceId = str ...
- (四)golang--注意事项
以.go为结尾: 执行入口是main()函数: 区分大小写: Go方法由一条条语句构成,每个语句后不需要加问号: Go编译器是一行行进行编译的,一行不能写多条语句: go语言定义的变量或者import ...
- 23 Maven工程module的移除和重新导入
1.移除module 移除后: 点击右侧的maven projects: 2.重新导入刚才移除的module (1)方法1 (2)方法2 Ctrl+Shift+ALT+S的快捷键 选择modules ...
- [转帖]腾讯云TStack获下一代云计算技术创新奖 与鲲鹏等产品实现兼容性测试
http://www.techweb.com.cn/cloud/2019-12-16/2769286.shtml [TechWeb]12 月 16 日消息,在中国电子技术标准化研究院主办的“第九届中国 ...
- Redis Persistent Replication Sentinel Cluster的一些理解
Redis Persistent Replication Sentinel Cluster的一些理解 我喜欢把工作中接触到的各种数据库叫做存储系统,笼统地说:Redis.Mysql.Kafka.Ela ...
- Appium+python自动化(四)- 如何查看程序所占端口号和IP(超详解)(番外篇)
简介 这篇博文和分类看似没有多大关系,但是也是从上一篇衍生出来的产物,因为涉及到FQ工具Lantern,就算是给关注和支持的小伙伴们拓展一下眼界和知识面.而且好多人都阅读了上一篇没发现那个参考博客点不 ...
- 2019-11-29-VisualStudio-使用三个方法启动最新-C#-功能
原文:2019-11-29-VisualStudio-使用三个方法启动最新-C#-功能 title author date CreateTime categories VisualStudio 使用三 ...
- 重绘MenuStrip 控件
重绘MenuStrip控件 效果如图: 首先添加 CustomProfessionalRenderer类 用于重绘控件菜单样式 /// <summary> /// 自定义MenuStrip ...
- C#操作XML文档
Note: '=> ' 表示返回值 参考资料:请点击这里! 1:创建Xml文档 2:写Xml文档(必须保证有根元素) XmlDocument Xd (实例化一个对象) CreateXmlDecl ...