P1607 [USACO09FEB]寺シャトルフェアシャトル

P1607 [USACO09FEB]寺シャトルフェアシャトル


タイトル:散歩市場、授与製品に対するプログラムはファーマージョンのためではなく、彼の牛は運動の非常に不足しているかを確認するには-あなたは、市場内のすべての日を歩いしたい場合、彼らは排出されます。牛は喜んで市場を訪れることができようにするには、準備ができて車市場でのジョンの牛を聞かせします。しかし、ジョン・ウッドお金が、彼はまっすぐなラインを実行し、そして唯一のドッキングできバザーに一度だけ一緒にバスを借りて(N(1≤N≤20000)\ \ ) の位置(すべての場所がNに1であります発現の間の数)。今、牛を分けた\(K(1≤K≤50000)\)のグループ、私は最初のグループ\(M_I(1≤M_i≤N)\ ) 彼らからしたい牛\(S_I \)が行ってきました(\をT_I(≤S_i。1 <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;
}

おすすめ

転載: www.cnblogs.com/jeffersonqin/p/11210925.html
おすすめ