AIsing Programming Contest 2020 E - Camel Train
阿新 • • 發佈:2020-07-22
題目意思很貪心,但有些放左邊好,有些放右邊好,一起做不好弄
可以分開做:一定存在一種最優方案,使得所有放在左邊更優的都在左側(存在一個分界點)
然後把兩個種類分開貪心,以左邊的為例:
用一個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; }