• NC50439 tokitsukaze and Soldier(贪心)


    题目链接

    题目大意

      略

    解题思路

      使用两个优先队列,第一个优先队列以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;
    }
    
  • 相关阅读:
    常用正则表达式
    C#链接常见数据库的方法
    [转]hibernate分页原理
    2020hdu多校第一场比赛及补题
    2020hdu多校第四场比赛及补题
    2020hdu多校第五场比赛及补题
    2020hdu多校第三场比赛及补题
    2020hdu多校第二场比赛及补题
    第二次vj团队赛补题
    字符串距离问题
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/13766449.html
Copyright © 2020-2023  润新知