【CF1019A】Elections

23 篇文章 0 订阅

题目

题意翻译
Berland地区的腐败现象非常常见。

马上有一场选举,你事先知道了选民和政党的数量,分别为 nn 和 mm ,对于每一位选民,你知道他将要选举哪一个政党,不过,每一位选民都会在接受一定数额的金钱之后改变他的主意。如果你给第 ii 位选民 c_ic
i
​ 数额的比特币,他就会选举任何你希望他选举的政党。

你的目的是让Berland的联合党赢得这场选举,联合党必须拥有比其它政党都多的选票,在此基础之上,你希望花费的比特币尽可能少。

输入格式

第一行包含两个整数 nn 和 mm .

接下来 nn 行每一行两个整数—— p_ip
i
​ 和 c_ic
i
​ ,这一位选民将会选举政党的编号,和使他改变主意的最少比特币数额。

特别地,联合党的编号是1.

输出格式

一个整数,使联合党赢得选举所需花费的最少比特币数额。

Berland地区的腐败现象非常常见。

马上有一场选举,你事先知道了选民和政党的数量,分别为 n n n m m m ,对于每一位选民,你知道他将要选举哪一个政党,不过,每一位选民都会在接受一定数额的金钱之后改变他的主意。如果你给第 i i i 位选民 c i c_i ci 数额的比特币,他就会选举任何你希望他选举的政党。

你的目的是让Berland的联合党赢得这场选举,联合党必须拥有比其它政党都多的选票,在此基础之上,你希望花费的比特币尽可能少。

输入格式

第一行包含两个整数 n n n m m m .

接下来 n n n 行每一行两个整数—— p i p_i pi c i c_i ci ,这一位选民将会选举政党的编号,和使他改变主意的最少比特币数额。

特别地,联合党的编号是1.

输出格式

一个整数,使联合党赢得选举所需花费的最少比特币数额。
题目描述
As you know, majority of students and teachers of Summer Informatics School live in Berland for the most part of the year. Since corruption there is quite widespread, the following story is not uncommon.

Elections are coming. You know the number of voters and the number of parties — n n and m m respectively. For each voter you know the party he is going to vote for. However, he can easily change his vote given a certain amount of money. In particular, if you give i i -th voter c_i c
i
​ bytecoins you can ask him to vote for any other party you choose.

The United Party of Berland has decided to perform a statistical study — you need to calculate the minimum number of bytecoins the Party needs to spend to ensure its victory. In order for a party to win the elections, it needs to receive strictly more votes than any other party.

输入输出格式
输入格式:
The first line of input contains two integers n n and m m ( 1 \le n, m \le 3000 1≤n,m≤3000 ) — the number of voters and the number of parties respectively.

Each of the following n n lines contains two integers p_i p
i
​ and c_i c
i
​ ( 1 \le p_i \le m 1≤p
i
​ ≤m , 1 \le c_i \le 10^9 1≤c
i
​ ≤10
9
) — the index of this voter’s preferred party and the number of bytecoins needed for him to reconsider his decision.

The United Party of Berland has the index 1 1 .

输出格式:
Print a single number — the minimum number of bytecoins needed for The United Party of Berland to win the elections.

输入输出样例
输入样例#1: 复制
1 2
1 100
输出样例#1: 复制
0
输入样例#2: 复制
5 5
2 100
3 200
4 300
5 400
5 900
输出样例#2: 复制
500
输入样例#3: 复制
5 5
2 100
3 200
4 300
5 800
5 900
输出样例#3: 复制
600
说明
In the first sample, The United Party wins the elections even without buying extra votes.

In the second sample, The United Party can buy the votes of the first and the fourth voter. This way The Party gets two votes, while parties 3 3 , 4 4 and 5 5 get one vote and party number 2 2 gets no votes.

In the third sample, The United Party can buy the votes of the first three voters and win, getting three votes against two votes of the fifth party.

思路

其实这个题是个贪心的题。但是这个题的贪心非常有意思,体现了正难则反的思想。一开始,我的贪心策略是用一个堆存所有的党派,每个党派里面又用堆来存支持者,然后从支持者人数多的党派里面选取价格最小的来行贿。很明显,这样的贪心策略是不正确的!那么什么是正确的贪心策略呢?首先我们可以发现如果从投票者作为出发点,来进行贪心,这样似乎很有难度。那么我们考虑从答案出发,枚举最后的答案。假设目前枚举的答案是A,除了1号党派以外,其他所有党派的支持人数都应该严格小于1号党派。也就是说,我们必须把其它所有支持人数大于A的党派里面价格最小的几个行贿了。如果最后1号党派的支持人数仍然没有达到A,那么我们就应该从小到大,把可以行贿(可以行贿的意思是之前没有行贿过)的人全部行贿了,直到最后支持者人数为A。我们只需要从1…n/2来枚举每个答案就行了。 但是要注意一个个坑: 1.如果只有1号党派,那么最后应该判断一下cost是否被更改过,如果没有,应该输出0.

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

struct person{
    int p,c;
}s[3005];

bool operator <(person a,person b){
    return a.c<b.c;
}

int n,m;
long long ans;
int p[3005];
bool v[3005];

int main()
{
    int i,j;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
	{
        scanf("%d%d",&s[i].p,&s[i].c);
        p[s[i].p]++;
    }
    int mv=p[1];
    sort(s+1,s+n+1);
    int t[3005];
    long long cnt,vote;
    ans=0x7fffffffffffffff;
    for(i=mv;i<=n;i++){
        memset(v,0,sizeof(v));
        memset(t,0,sizeof(t));
        cnt=vote=0;
        for(j=1;j<=n;j++){
            if(s[j].p==1){
                vote++,v[j]=1;
                continue;
            }
            if(p[s[j].p]-t[s[j].p]>=i){
                cnt+=s[j].c,v[j]=1,t[s[j].p]++,vote++;
            }
        }
        j=1;
        while(vote<i){
            if(!v[j])cnt+=s[j].c,vote++;
            j++;
        }
        ans=min(ans,cnt);
    }

    cout<<ans<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值