Codeforces Round #513 D. Social Circles 贪心

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiang_6/article/details/83903388

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

猜你喜欢

转载自blog.csdn.net/xiang_6/article/details/83903388