Martian148's blog Martian148's blog
首页
  • ICPC 算法笔记
  • ICPC 算法题解
  • 体系结构
  • 高等数学
  • 线性代数
  • 概率论与数理统计
  • 具体数学
  • Martian148的奇思妙想
  • 游记
  • 通识课笔记
关于
  • useful 网站
  • 友情链接
  • 分类
  • 归档

Martian148

一只热爱文科的理科生
首页
  • ICPC 算法笔记
  • ICPC 算法题解
  • 体系结构
  • 高等数学
  • 线性代数
  • 概率论与数理统计
  • 具体数学
  • Martian148的奇思妙想
  • 游记
  • 通识课笔记
关于
  • useful 网站
  • 友情链接
  • 分类
  • 归档
  • codeforses 题解

  • atcoder 题解

  • XCPC 题解

  • 校训练赛题解

  • 牛客题解

  • 蓝桥杯题解

  • 典题选讲

    • CF2025E Card Game (动态规划、多项式快速幂、银牌题)
    • CF2026E Best Subsequence(网络流、最大权闭合图,铜牌题)
    • 牛客多校6 C Stack(数论,第一类斯特林数,铜牌题)
    • Zero
    • Elevator II
    • 算法题解
    • 典题选讲
    martian148
    2025-10-02
    目录

    Elevator II

    # Elevator II

    The 2024 ICPC Asia Hangzhou Regional Contest E

    # Question

    有一部电梯,nnn 个人,第 iii 个人需要从第 lil_ili​ 层到第 rir_iri​ 层(li<ril_i<r_ili​<ri​),电梯上升一层需要 1 的代价,下降不需要代价,电梯刚开始在第 fff 层,电梯一次只能带一个人

    需要你构造出一个排列,保证能满足所有人的需求,并且代价最小

    输出最小代价和排列

    # Solution

    考虑答案的上界

    首先,每一趟电梯的距离是不可以省去的,即 ∑(rai−lai)\sum (r_{a_i}-l_{a_i})∑(rai​​−lai​​)

    还有就是从 fff 到 max⁡{r}\max\{r\}max{r} 这趟距离

    我们很容易可以构造出这样的方法,第一步就是从 fff 到 max⁡{r}\max\{r\}max{r} 然后把电梯按照 rrr 排序,从大到小运送即可

    但是其实我们在从 fff 到 max⁡{r}\max\{r\}max{r} 的过程中可以顺带着把一些人带上去,这里就用到了贪心的想法

    如果当前我们在的位置是 ppp 那么我们可以选择 lll 小于 ppp 且 rrr 大于 ppp 的那个人送上去,如果不存在这样的人,就去找下一个 lll 最小的那个人,这可以用一个指针完成

    # Code

    #include <bits/stdc++.h>
    using namespace std;
    
    struct Node {
        int l, r, id;
    };
    
    bool cmpl(const Node &a, const Node &b) {
        return a.l < b.l || (a.l == b.l && a.r > b.r);
    }
    
    bool cmpr(const Node &a, const Node &b) {
        return a.r > b.r;
    }
    
    
    void solve() {
        int n, f; cin >> n >> f;
        vector<Node> a(n + 1);
    
        for (int i = 1; i <= n; i++) {
            cin >> a[i].l >> a[i].r;
            a[i].id = i;
        }
    
        sort(a.begin() + 1, a.end(), cmpl);
        vector<int> ans;
        vector<int> vis(n + 1, 0);
    
        long long sum = 0;
        int now = f;
        for (int i = 1; i <= n; i++) {
            if (a[i].l <= now && a[i].r <= now) continue;
            if (a[i].l > now) sum += a[i].l - now;
            sum += a[i].r - a[i].l;
            ans.push_back(a[i].id);
            vis[a[i].id] = 1;
            now = a[i].r;
        }
    
        sort(a.begin() + 1, a.end(), cmpr);
        for (int i = 1; i <= n; i++) {
            if (vis[a[i].id]) continue;
            sum += a[i].r - a[i].l;
            ans.push_back(a[i].id);
            vis[a[i].id] = 1;
        }
    
        cout << sum << "\n";
        for (auto id : ans)
            cout << id << " ";    
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
    
        int t; cin >> t;
        while (t--) solve();
        return 0;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    Zero

    ← Zero

    最近更新
    01
    打破信息差,一条学校不教的计算机学习之路
    09-18
    02
    Zero
    09-18
    03
    模型与分词器
    09-17
    更多文章>
    Theme by Vdoing | Copyright © 2024-2025 Martian148 | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式