Codeforces Round #503 (by SIS, Div. 2)C. Elections

AC code:

#include<bits/stdc++.h>
using namespace std;
int n = 0,m = 0,x = 0,y = 0;
typedef long long LL;
LL ans = 1e18;
multiset<int> v,p[3005];
int main(){
    scanf("%d %d",&n,&m);
    for(int i = 0;i < n;++i){
        scanf("%d %d",&x,&y);
        p[x].insert(y);//每一个party所需要的票价 
        if(x != 1){
            v.insert(y);//收买其他人的票价
        }
    }
    int tkn = 0;
    LL rem = 0;
    for(int i = n;i >= 1;--i){
        for(int j = 2;j <= m;++j){
            if(p[j].size() < i){//类似于将最大票数控制在i以下 
                continue;
            }

            while(p[j].size() >= i){//类似于将最大票数控制在i以下 
                ++tkn;              //目前取走的高于 i的票
                rem += *(p[j].begin()); //set集合自动排序,取出最小值 
                v.erase(v.find(*p[j].begin()) );//j不小心写成i了,改了我好久,无语 
                p[j].erase(p[j].begin());//要先在v里面清除,在再在p里面清除 
            }
        }
        LL res = rem;
        int cnt = i - (int)p[1].size() - tkn;//这是1与其他政党中票数最多的政党的大小比较 
        for(auto a : v){
            if(cnt <= 0){//cnt<=0说明不需要更多的票数了,否则还需要全局最小票数,来凑数超越第一大党
            //其中可能选第一大党的票数,是他的票数-1,效果等价于-2,但是这里贪心没考虐
            //但是后面遍历i时,会把这种情况算进去 
                break;
            }
            res += a;
            --cnt;
        }
        ans = min(res,ans);

    }
    printf("%I64d\n",ans);
    //cout << ans << endl;


    return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值