1. 程式人生 > >Codeforces Round #513 D. Social Circles 貪心

Codeforces Round #513 D. Social Circles 貪心

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;
//}