zoukankan      html  css  js  c++  java
  • codeforces#1251E2. Voting (Hard Version)(贪心)

    题目链接:

    http://codeforces.com/contest/1251/problem/E2

    题意:

    主角需要获得n个人的投票

    有两种方式让某个人投票

    1,已经投票的人数大于m

    2,花p枚硬币收买

    数据范围:

    $1leq n leq 200 000$

    分析: 

    对$m$进行排序

    保留前缀的$m$数组,$pre[x]$为$m$小于等于$x$的人数

    对x逆序处理,当枚举到$x$的时候,假设$m$小于等于$x-1$的那些人已经投票,也就是有$pre[x-1]$人已经投票

    如果$pre[x-1]>=x$那么不需要处理

    如果$pre[x-1]<x$那么$m$在$x$到$n$的人至少要收买$x-pre[x-1]$个人

    得到所有$x$需要收买的后缀,显然,从后往前处理最优

    AC代码:

    #include <bits/stdc++.h>
    #define ll long long
    #define pii pair<int,int>
    using namespace std;
    const int maxn=2e5+7;
    int pre[maxn];
    vector<int>ve[maxn];
    multiset<int>se;
    int main() {
        int T,n;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            for(int i=1;i<=n;i++){
                int a,b;
                scanf("%d %d",&a,&b);
                pre[a]++;
                ve[a].push_back(b);
            }
            for(int i=1;i<=n;i++)
                pre[i]+=pre[i-1];
            int cnt=0;
            ll ans=0;
            for(int i=n;i>=1;i--){
                for(int j=0;j<ve[i].size();j++)se.insert(ve[i][j]);
                int v=i-cnt-pre[i-1];
                while(v>0){
                    ans+=(*se.begin());
                    se.erase(se.begin());
                    v--;
                    cnt++;
                }
            }
            se.clear();
            for(int i=0;i<=n;i++)ve[i].clear(),pre[i]=0;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    Eclipse下Tomcat插件的安装
    支付宝接口资料解读
    文件转换器服务推荐
    接吻的学问
    Web小工具推荐
    两个优秀的免费字体资源
    每年考证时间
    Visual Studio 2008 简体中文版和MSDN下载
    生活小经验
    UIScrollView and lazy loading
  • 原文地址:https://www.cnblogs.com/carcar/p/11761552.html
Copyright © 2011-2022 走看看