zoukankan      html  css  js  c++  java
  • Npc50C [贪心]

    Npc 50CNpc 50C

    在一个游戏中,tokitsukaze需要在n个士兵中选出一些士兵组成一个团去打副本。
    第i个士兵的战力为v[i],团的战力是团内所有士兵的战力之和。
    但是这些士兵有特殊的要求:如果选了第i个士兵,这个士兵希望团的人数不超过s[i]。(如果不选第i个士兵,就没有这个限制。)
    tokitsukaze想知道,团的战力最大为多少。

    1n1051≤n≤10^5
    1v109,1sn1≤v≤10^9,1≤s≤n


    color{red}{正解部分}

    发现如果按照 v[i]v[i] 从大到小贪心的话, 团的人数限制不好处理, 因为不知道是哪个士兵限制了团的人数大小 .

    于是按照 s[i]s[i] 从大到小排序, 从左往右选择士兵, 限制团大小的士兵肯定包括 ii 和 与 ii s[i]s[i] 相等的士兵,

    ii 这个士兵的限制下, 要尽量使得战力更大, 即选择最大的, 丢弃最小的,
    于是可以使用小根堆维护当前的士兵集合, 若不符合条件, 就不断地往外弹出 vv 最小的士兵, 直到符合条件, 更新答案 .


    color{red}{实现部分}

    #include<bits/stdc++.h>
    typedef long long ll;
    #define reg register
    
    const int maxn = 1e5 + 10;
    
    int N;
    
    ll Ans;
    ll cur_sum;
    
    struct Node{ int s, v; } A[maxn];
    
    bool cmp(Node a, Node b){ return a.s > b.s; }
    
    int main(){
            scanf("%d", &N);
            for(reg int i = 1; i <= N; i ++) scanf("%d%d", &A[i].v, &A[i].s);
            std::sort(A+1, A+N+1, cmp);
            std::priority_queue <int, std::vector<int>, std::greater<int> > Q;
            for(reg int i= 1; i <= N; i ++){
                    Q.push(A[i].v), cur_sum += A[i].v;
                    while((int)Q.size() > A[i].s) cur_sum -= Q.top(), Q.pop();
                    Ans = std::max(Ans, cur_sum);
            }
            printf("%lld
    ", Ans);
            return 0;
    }
    
  • 相关阅读:
    调试SQL Server的存储过程及用户定义函数
    寻找 vb.net 事务处理高级编程 的代码!!
    解析Java类和对象的初始化过程
    SQL 安装进程被挂起!
    教你成为一个受欢迎的人
    final class作用
    微软反跨站脚本库
    pdf解析
    ce'shi测试微博
    淘宝架构变化
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822516.html
Copyright © 2011-2022 走看看