• CodeForces


    You are running for a governor in a small city in Russia. You ran some polls and did some research, and for every person in the city you know whom he will vote for, and how much it will cost to bribe that person to vote for you instead of whomever he wants to vote for right now. You are curious, what is the smallest amount of money you need to spend on bribing to win the elections. To win elections you need to have strictly more votes than any other candidate.


    Input

    First line contains one integer n (1 ≤ n ≤ 105) — number of voters in the city. Each of the next n lines describes one voter and contains two integers ai and bi (0 ≤ ai ≤ 105; 0 ≤ bi ≤ 104) — number of the candidate that voter is going to vote for and amount of money you need to pay him to change his mind. You are the candidate 0 (so if a voter wants to vote for you, ai is equal to zero, in which case bi will also be equal to zero).

    Output

    Print one integer — smallest amount of money you need to spend to win the elections.

    Examples
    Input
    5
    1 2
    1 2
    1 2
    2 1
    0 0
    Output
    3
    Input
    4
    1 2
    1 2
    2 1
    0 0
    Output
    2
    Input
    1
    100000 0
    Output
    0

    题意:给定N个voter,给个人有自己准备投的人ai,以及费用bi,表示可以用bi元钱去收买他他让改变主意。问0号选手至少花多少钱,使得他的voter最多。

    思路:不难想到二分0号选手的voter数,但是二分是WA的,因为单调性有个临界值,小于这个临界值,无法保证0号是最多的。 直接三分。

    (注意不要用二分,因为并非是收买的人越多,代价越高。 有可能收买的人越多,可供选择的越多,使得低价的越多,所以必须三分。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=100010;
    int num[maxn],ans=1<<30,N;
    vector<int>G[maxn]; int q[maxn],cnt;
    int check(int Mid)
    {
        int tnum=num[0]+Mid,res=0,tot=0;
        rep(i,1,100000){
            rep(j,0,max(-1,num[i]-tnum)) tot++,res+=G[i][j];
        }
        if(tot>Mid) return 1<<30; cnt=0; //不足以成为最多,反正一个极大值
        rep(i,1,100000){
            rep(j,max(0,num[i]-tnum+1),num[i]-1) q[++cnt]=G[i][j];
        }
        sort(q+1,q+cnt+1);
        rep(i,1,Mid-tot) res+=q[i];
        return res;
    }
    int main()
    {
        int x,y;
        scanf("%d",&N);
        rep(i,1,N){
            scanf("%d%d",&x,&y);
            if(x==0||y==0) num[0]++;
            else G[x].push_back(y),num[x]++;
        }
        rep(i,1,100000) sort(G[i].begin(),G[i].end());
        int F=true;
        rep(i,1,N) if(num[i]>=num[0]) F=false;
        if(F) return puts("0"),0;
        int L=1,R=N,Mid1,Mid2,f1,f2;
        while(L<=R){
            Mid1=L+(R-L)/3; f1=check(Mid1);
            Mid2=R-(R-L)/3; f2=check(Mid2);
            if(f1<=f2) R=Mid2-1,ans=min(ans,f1);
            else L=Mid1+1,ans=min(ans,f2);
        }
        printf("%d
    ",ans);
        return 0;
    }
    
     
  • 相关阅读:
    android系统属性获取及设置
    Android Strings.xml To CSV / Excel互转
    android adb命令 抓取系统各种 log
    Android开源日志库Logger的使用
    解决git仓库从http转为ssh所要处理的问题
    PHP中var_dump
    oracle文字与格式字符串不匹配的解决
    Apache服务器和tomcat服务器有什么区别?
    【手把手教你Maven】构建过程
    Spring MVC页面重定向
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10179371.html
Copyright © 2020-2023  润新知