Codeforces Round #513 D. Social Circles 貪心
阿新 • • 發佈:2018-11-13
CF: greedy math *1900;
題意:
給定n個人,每個人坐下以後,左邊要有l[i]個座位,右邊要有r[i]個座位;一個人一張桌子時可以把左右兩邊看作重合;
思路:
一開始想了個假演算法,首先對於i這個人 l[i] == r[i] 時候,可以直接把他放在單獨的一張桌子上,因為思考發現他和別的人一起坐也不會優化答案; 然後按照左右兩邊大小分成兩組,一個是r[i] > l[i] 的,另一個是 l[i] > r[i];的,然後開始看作每個人都一張桌子,把他們放在優先佇列裡,按最大值從大到小排序,這樣想是因為我想讓最大值最大的兩個人坐在一張桌子上(合併);
發現上述演算法不對後,但是能確定當合並兩個人時,每個人貢獻的是最大值;
正解是:把所有人的l[i],r[i] 分別考慮,從小到大排序,一一對應的情況下,每個選取max(l[i],r[i])+1,(+1是因為人要佔一個位置);
之所以這樣做可行,是因為我們不需要管他怎麼合併,按照上述左右兩邊值儘量大的兩個人合併在一起就行,如果要是l[i],r[i] 恰好來自同一個人呢?那就是這個人自己一張位子的時候;
#include<bits/stdc++.h> using namespace std; #define out fflush(stdout); #define fast ios::sync_with_stdio(0),cin.tie(0); #define FI first #define SE second typedef long long ll; typedef pair<ll,ll> P; const int maxn = 2e5 + 7; const int INF = 0x3f3f3f3f; const ll mod = 998244353; int n; ll ans = 0; int l[maxn], r[maxn]; int main() { scanf("%d", &n); for(int i = 1; i <= n; ++i) { scanf("%d%d", &l[i], &r[i]); } sort(l+1, l+1+n); sort(r+1, r+1+n); for(int i = 1; i <= n; ++i) { ans += (max(l[i], r[i]) + 1); } printf("%lld\n", ans); return 0; } //int n; //ll ans = 0; // //struct node { // ll l, r; // ll max_; // bool operator>(const node &a) const { // return (max_ < a.max_); // } //}; //priority_queue<node, vector<node>, greater<node> > qu1, qu2; // // //void solve() { // if(qu1.empty() || qu2.empty()) return; // node t1 = qu1.top(); qu1.pop(); // node t2 = qu2.top(); qu2.pop(); // while(1) { // cout << t1.l << " " << t1.r << " +++++ " << t2.l << " " << t2.r << endl; // if(t1.max_ == t2.max_) { // ll a = t1.l, b = t2.r; // ll c = max(a, b); // ll d = min(t1.r, t2.l); // // ans += (c - d); // if(a > b) { // qu1.push(node{a, b, c}); // } // else if(a < b) { // qu2.push(node{a, b, c}); // } // if(qu1.empty() || qu2.empty()) return; // t1 = qu1.top(); qu1.pop(); // t2 = qu2.top(); qu2.pop(); // } // else if(t1.max_ > t2.max_) { // if(qu1.empty() || qu2.empty()) return; // t1 = qu1.top(); qu1.pop(); // } // else { // if(qu1.empty() || qu2.empty()) return; // t2 = qu2.top(); qu2.pop(); // } // } //} // //int main() { // scanf("%d", &n); // ll a, b; // for(int i = 1; i <= n; ++i) { // scanf("%lld%lld", &a, &b); // if(a == b) { // ans += (a + 1); // } // else { // ll t = max(a, b); // ans += (t + 1); // if(a < b) qu1.push(node{a, b, t}); // else qu2.push(node{a, b, t}); // } // } // solve(); // printf("%lld\n", ans); // return 0; //}