首页 > 其他 > 详细

NC50439 tokitsukaze and Soldier(贪心)

时间:2020-10-04 09:56:13      阅读:37      评论:0      收藏:0      [点我收藏+]

题目链接

题目大意

??略

解题思路

??使用两个优先队列,第一个优先队列以v为第一优先级,s为第二优先级从大到小排序,第二个优先队列以s为第一优先级,v为第二优先级从小到大排序。对于第一个优先队列堆顶的一对(v,s)来说,如果s我们选出的所有数的数量小,就不需要他了,因为我们以v的大小为第一优先级,加上他最少需要减去一个比他更大的数,然后我们把符合条件的数加入第二个优先队列。
??由于可能有前面v比较大的数s比较小,当s最小的数的s已经比当前选出的数小时,需要去掉这个数来给其他的数腾出位置,这就是第二个优先队列的意义。

代码

const int maxn = 1e5+10;
const int maxm = 1e4+10;
struct INFO {
    int v, s;
    bool operator < (const INFO &a) const {
        return v==a.v ? s<a.s:v<a.v;
    }
};
struct INFO2 {
    int v, s;
    bool operator < (const INFO2 &a) const {
        return s==a.s ? v>a.v:s>a.s;
    }
};
int n;
priority_queue<INFO> pq;
priority_queue<INFO2> pq2;
int main(void) {
    cin >> n;
    ll sum = 0, ans = 0;
    for (int i = 0, a, b; i<n; ++i) {
        scanf("%d%d", &a, &b);
        pq.push({a, b});
        //cout << pq.top().v << endl;
    }
    while(!pq.empty()) {
        int a = pq.top().v, b = pq.top().s; pq.pop();
        if (b<=pq2.size()) continue;
        pq2.push({a, b});
        sum += a;
        if (pq2.top().s<pq2.size()) sum -= pq2.top().v, pq2.pop();
        ans = max(ans, sum);
    }
    cout << ans << endl;
    return 0;
}

NC50439 tokitsukaze and Soldier(贪心)

原文:https://www.cnblogs.com/shuitiangong/p/13766449.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!