• noip模拟赛 公交车


    题目描述
    LYK在玩一个游戏。
    有k群小怪兽想乘坐公交车。第i群小怪兽想从xi出发乘坐公交车到yi。但公交车的容量只有M,而且这辆公交车只会从1号点行驶到n号点。
    LYK想让小怪兽们尽可能的到达自己想去的地方。它想知道最多能满足多少小怪兽的要求。
    当然一群小怪兽没必要一起上下车,它们是可以被分开来的。

    输入格式(bus.in)
    第一行三个数k,n,M。
    接下来k行每行3个数xi,yi和ci。其中ci表示第i群小怪兽的小怪兽数量。

    输出格式(bus.out)
    一个数表示最多有多少只小怪兽能满足要求。

    输入样例
    3 5 3
    1 3 4
    3 5 2
    1 5 3

    输出样例
    5

    样例解释
    第一群的3只小怪兽在1号点上车,并在3号点下车。
    第二群的2只小怪兽在3号点上车,5号点下车。

    数据范围
    对于30%的数据小怪兽的总数不超过10只,n<=10。
    对于另外30%的数据k,n<=1000。
    对于100%的数据1<=n<=20000,1<=k<=50000,1<=M<=100,1<=ci<=100,1<=xi<yi<=n。

    分析:把一群小怪兽看做一条有权值的线段,那么就把题目转化为了覆盖尽量多的线段,使他们尽量不想交,这就是一类经典的贪心问题了.

          先把所有的线段按照右端点排序,用一个数组f记录第i个时刻车上已经有多少人了,因为是按照右端点排序的,所以每次加满人一定是最优的,因为加人是影响到后面的操作的,已经按照右端点排序了,所以对后面的影响最小,那么查询一下[x,y]中最多有多少人,然后把能放上的人全部放上去.

          涉及到区间求最大值和区间修改,可以用线段树来优化.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int k, n, m, maxx[200010], tag[200010], ans;
    
    struct node
    {
        int x, y, c;
    }e[50010];
    
    void pushup(int o)
    {
        maxx[o] = max(maxx[o * 2], maxx[o * 2 + 1]);
    }
    
    bool cmp(node a, node b)
    {
        if (a.y == b.y)
            return a.x > b.x;
        return a.y < b.y;
    }
    
    void pushdown(int o)
    {
        if (tag[o])
        {
            tag[o * 2] += tag[o];
            tag[o * 2 + 1] += tag[o];
            maxx[o * 2] += tag[o];
            maxx[o * 2 + 1] += tag[o];
            tag[o] = 0;
        }
    }
    
    void update(int o, int l, int r, int x, int y, int v)
    {
        if (x <= l && r <= y)
        {
            tag[o] += v;
            maxx[o] += v;
            return;
        }
        pushdown(o);
        int mid = (l + r) >> 1;
        if (x <= mid)
            update(o * 2, l, mid, x, y, v);
        if (y > mid)
            update(o * 2 + 1, mid + 1, r, x, y, v);
        pushup(o);
    }
    
    int query(int o, int l, int r, int x, int y)
    {
        if (x <= l && r <= y)
            return maxx[o]; 
        pushdown(o);
        int mid = (l + r) >> 1, res = 0;
        if (x <= mid)
            res = max(res, query(o * 2, l, mid, x, y));
        if (y > mid)
            res = max(res, query(o * 2 + 1, mid + 1, r, x, y)); 
        return res;
    }
    
    int main()
    {
        scanf("%d%d%d", &k, &n, &m);
        for (int i = 1; i <= k; i++)
            scanf("%d%d%d", &e[i].x, &e[i].y, &e[i].c);
        sort(e + 1, e + 1 + k, cmp);
        for (int i = 1; i <= k; i++)
        {
            int temp = query(1, 1, n, e[i].x, e[i].y), res = 0;
            if (temp >= m)
                continue;
            if (temp + e[i].c <= m)
                res = e[i].c;
            else
                res = m - temp;
            ans += res;
            update(1, 1, n, e[i].x, e[i].y - 1, res);
        }
        printf("%d
    ", ans);
    
        return 0;
    }
  • 相关阅读:
    charles使用教程指南
    根域名服务器 根服务器一般指根域名服务器 (DNS)
    DNS原理及其解析过程【精彩剖析】
    代理工具Charles使用
    cisco 为每个单独的人员设置不同的用户名和密码
    大数据架构:flume-ng+Kafka+Storm+HDFS 实时系统组合
    KAFKA分布式消息系统
    Android 监听屏幕锁屏,用户解锁
    如何判断微信内置浏览器
    Android,iOS,浏览器打开手机QQ与指定用户聊天界面
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7683192.html
Copyright © 2020-2023  润新知