【题目链接】

【题目概括】

现在有\(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」回家路线的更多相关文章

  1. LOJ 3156: 「NOI2019」回家路线

    题目传送门:LOJ #3156. 题意简述: 有一张 \(n\) 个点 \(m\) 条边的有向图,边有两个权值 \(p_i\) 和 \(q_i\)(\(p_i<q_i\))表示若 \(p_i\) ...

  2. loj3161「NOI2019」I 君的探险(随机化,整体二分)

    loj3161「NOI2019」I 君的探险(随机化,整体二分) loj Luogu 题解时间 对于 $ N \le 500 $ 的点,毫无疑问可以直接 $ O(n^2) $ 暴力询问解决. 考虑看起 ...

  3. 【LOJ】#2068. 「SDOI2016」探险路线

    题解 少考虑了情况,导致我以为是暴力讨论一次角落移动 de了两天才反应过来--简直降智 事实上,我们把移动分三类,一种是在边界跳过一段,一种是在左上角上左上左上左这样撞墙,在右下角下右下右下右这么撞墙 ...

  4. LOJ 3158: 「NOI2019」序列

    题目传送门:LOJ #3158. 题意简述: 给定两个长度为 \(n\) 的正整数序列 \(a,b\),要求在每个序列中都选中 \(K\) 个下标,并且要保证同时在两个序列中都被选中的下标至少有 \( ...

  5. LOJ 3160: 「NOI2019」斗主地

    题目传送门:LOJ #3160. 简要题意: 有一个长度为 \(n\) 的序列 \(a\),初始时 \(a_i=i\) 或 \(a_i=i^2\),这取决于 \(\mathrm{type}\) 的值. ...

  6. LOJ 3159: 「NOI2019」弹跳

    题目传送门:LOJ #3159. 题意简述: 二维平面上有 \(n\) 个整点,给定每个整点的坐标 \((x_i,y_i)\). 有 \(m\) 种边,第 \(i\) 种边从 \(p_i\) 号点连向 ...

  7. 「NOI2019」弹跳(KD树)

    题意:w×h网格中有n个点,m条边.每条边可以从p点花费t时间到一个矩形中的任意点,求1号点到每个点的最少时间. \(1<=w,h<=n<=70000,1<=m<=150 ...

  8. @loj - 3157@「NOI2019」机器人

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 R 喜欢研究机器人. 最近,小 R 新研制出了两种机器人,分 ...

  9. 「NOI2019」序列

    NKOJ卡常卡不过QAQ description 给两个A,B序列,让你分别在A,B中各选k个数,其中至少有L对下标相等. Solution 把问题转化为至多选n-K对下标不同的对. 配对问题就用费用 ...

随机推荐

  1. Luogu P4118 [Ynoi2016]炸脖龙I

    题目 首先考虑没有修改的情况.显然直接暴力扩展欧拉定理就行了,单次复杂度为\(O(\log p)\)的. 现在有了修改,我们可以树状数组维护差分数组,然后\(O(\log n)\)地单次查询单点值. ...

  2. HYSBZ 1797 Mincut 最小割

    Descrption A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路.设其中第i (1≤i≤M)条道路连接了vi,ui两个中转站,那么中转站vi可以通过该道路到达ui中转站, ...

  3. 如何利用 CSS 的动画原理,创作一个乒乓球对打动画

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/rvgLzK 可交互视频教 ...

  4. innodb中一颗B+树能存储多少条数据

    如图,为B+树组织数据的方式: 实际存储时当然不会每个节点只存3条数据. 以InnoDB引擎为例,简单计算一下一颗B+树可以存放多少行数据. B+树特点:只有叶子节点存储数据,而非叶子节点存放的是用来 ...

  5. vue跳转新页面后回到顶部

    全部页面的话就在mian.js中设置或者 单独的某个页面就在页面加载之前设置 单独设置需变为this.$router router.afterEach((to,from,next)=>{ win ...

  6. Hyperledger Fabric(4)链码ChainCode

    智能合约,是一个抽象的概念,智能合约的历史可以追溯到 1990s 年代.它是由尼克萨博(Nick Szabo)提出的理念,几乎与互联网同龄. 我们这里所说的智能合约只狭义的指区块链中.它能够部署和运行 ...

  7. jquery 知识整理

    大纲一.jQuery简介 二.jQuery 和Dom关系及jQuery版本 1.jQuery版本 2.jQuery和Dom转换 三.jQuery 选择器 1.1.基本 1.2.层级 2.基本筛选器 3 ...

  8. 框架之一:mybatis

    同时加载驱动包 mysql+mybatis 创建bean对应的mapper接口bookMapper package com.imu.mzw.mapper; import java.util.List; ...

  9. 11、Nginx反向代理服务

    1Nginx代理服务基本概述 1.代理一词并不陌生, 该服务我们常常用到如(代理理财.代理租房.代理收货等等),如下图所示 2.在没有代理模式的情况下,客户端和Nginx服务端,都是客户端直接请求服务 ...

  10. 4G漏洞

    4G VoLTE漏洞:可致用户地理位置和其它个人信息泄露 2017-08-05 LBS 首先要了解下,什么是VoLTE. VoLTE为英文Voice Over LTE的缩写,直译就是音频通过LTE网络 ...