• P1607 [USACO09FEB]庙会班车Fair Shuttle


    P1607 [USACO09FEB]庙会班车Fair Shuttle


    题目:逛逛集市,兑兑奖品,看看节目对农夫约翰来说不算什么,可是他的奶牛们非常缺乏锻炼——如果要逛完一整天的集市,他们一定会筋疲力尽的。所以为了让奶牛们也能愉快地逛集市,约翰准备让奶牛们在集市上以车代步。但是,约翰木有钱,他租来的班车只能在集市上沿直线跑一次,而且只能停靠(N(1 ≤N≤20000))个地点(所有地点都以1到N之间的一个数字来表示)。现在奶牛们分成(K(1≤K≤50000))个小组,第i 组有(M_i(1 ≤M_i≤N))头奶牛,他们希望从(S_i)跑到(T_i(1 ≤S_i<T_i≤N))

    由于班车容量有限,可能载不下所有想乘车的奶牛们,此时也允许小里的一部分奶牛分开乘坐班车。约翰经过调查得知班车的容量是(C(1≤C≤100)),请你帮助约翰计划一个尽可能满足更多奶牛愿望的方案。


    题解:

    对于这道题,很显然是一道贪心,而且我们必须将其考虑为有反悔机制的贪心。首先在每一站,进行一下的判断:

    1. 将在车上的奶牛可以下车的下车
    2. 让所有在此站点上车的奶牛上车
    3. 如果超过数量,将最远目的地的奶牛赶下车
    #include <iostream>
    #include <set>
    #include <algorithm>
    
    using namespace std;
    typedef long long ll;
    
    const int maxn = 500005;
    
    // 一组牛
    struct group {
        ll s, t, m;
        group() {}
        group(ll s, ll t, ll m) : s(s), t(t), m(m) {}
      	// set内部按照终点站顺序排序
        friend bool operator < (const group &a, const group &b) {
            return a.t < b.t;
        }
    } cows[maxn];
    ll k, n, c, sum_on_car, ans;
    
    // 在车上的牛的组
    multiset<group> cow_set;
    
    // 按照起点站顺序排序
    bool cmp(group a, group b) {
        if (a.s == b.s) {
            if (a.t == b.t) {return a.m < b.m;}
            else {return a.t < b.t;}
        } else {return a.s < b.s;}
    }
    
    int main() {
      	// 读
        cin >> k >> n >> c;
        for (int i = 1; i <= k; i ++)
            cin >> cows[i].s >> cows[i].t >> cows[i].m;
        sort(cows + 1, cows + 1 + k, cmp);
      	// 从第一站开始遍历上车
        for (int i = 1, j = 0; i <= n; i ++) {
            multiset<group>::iterator begin_iter = cow_set.begin();
          	// 到站下车 (终点站顺序排序)
            while (begin_iter -> t == i) {
                sum_on_car -= begin_iter -> m;
                cow_set.erase(begin_iter);
                begin_iter = cow_set.begin();
            }
          	// 全部上车
            for (int t = j + 1; t <= k && cows[t].s == i; t ++) {
                j ++;
                cow_set.insert(cows[t]);
                sum_on_car += cows[t].m;
                ans += cows[t].m;
            }
          	// 人数超标,删最远的牛
            while (sum_on_car > c) {
                ll delta = sum_on_car - c;
                multiset<group>::iterator iter = cow_set.end();
                iter --;
                ll all_cow_farthest = iter -> m;
                cow_set.erase(iter);
                if (delta >= all_cow_farthest) {
                    sum_on_car -= all_cow_farthest;
                    ans -= all_cow_farthest;
                } else {
                    ll cow_tmp_s = iter -> s, cow_tmp_t = iter -> t, cow_tmp_m = iter -> m;
                    cow_set.insert(group(cow_tmp_s, cow_tmp_t, all_cow_farthest - delta));
                    sum_on_car -= delta;
                    ans -= delta;
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    MySQL 对于千万级的大表要怎么优化?
    随便写的一些docker使用操作命令
    零基础学python大概要多久?我用了30天
    普通人学python有意义吗?意义重大
    华为私有云组件
    Mysql 调优(二)分析思路
    MySQL 调优(一)调优原则
    shell脚本获取当前时间,分钟之前时间、小时之前时间和天之前时间
    java_windows环境变量自动设置脚本
    plsql中文乱码问题解决方案
  • 原文地址:https://www.cnblogs.com/jeffersonqin/p/11210925.html
Copyright © 2020-2023  润新知