1. 程式人生 > 實用技巧 >AIsing Programming Contest 2020 E - Camel Train

AIsing Programming Contest 2020 E - Camel Train

題目

題目意思很貪心,但有些放左邊好,有些放右邊好,一起做不好弄

可以分開做:一定存在一種最優方案,使得所有放在左邊更優的都在左側(存在一個分界點)

然後把兩個種類分開貪心,以左邊的為例:

用一個set儲存還沒放的位置

將所有camels按照Ri-Li排序,從大的開始處理,如果能放,就放在能放的最靠右的位置,否則直接放在最右側

#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
void read (int &x) {
    char ch = getchar(); x = 0;
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch)) x = x * 10 + ch - 48, ch = getchar();
} const int N = 2e5 + 10;
int n, k[N], l[N], r[N];
pair<int, int> p[N];
#define x first
#define y second
set<int> s;
vector<pair<int, int> > va, vb;
signed main() {
    int T; read (T);
    while (T--) {
        read (n); long long res = 0;
        va.clear(), vb.clear();
        for (int i = 1; i <= n; ++i) {
            read (k[i]), read (l[i]), read (r[i]);
            if (l[i] >= r[i])
                res += r[i], va.push_back (make_pair(l[i] - r[i], k[i]));
            else res += l[i], vb.push_back (make_pair(r[i] - l[i], n - k[i]));
        }
        s.clear(); sort (va.begin(), va.end());
        for (int i = 1; i <= va.size(); ++i) s.insert (i);
        set<int>::iterator it;
        for (int i = va.size() - 1; i >= 0; --i) {
            it = s.upper_bound (va[i].y);
            if (it == s.begin()) it = s.end(), --it, s.erase (it);
            else --it, s.erase (it), res += va[i].x;
        }
        s.clear(); sort (vb.begin(), vb.end());
        for (int i = 1; i <= vb.size(); ++i) s.insert (i);
        for (int i = vb.size() - 1; i >= 0; --i) {
            it = s.upper_bound (vb[i].y);
            if (it == s.begin()) it = s.end(), --it, s.erase (it);
            else --it, s.erase (it), res += vb[i].x;
        } printf ("%lld\n", res);
    }
    return 0;
}