Codeforces Round #503 (by SIS, Div. 1) - A . Elections (1019A)

本文探讨了一个涉及投票策略的问题,目标是最小化使1号竞选者获胜所需的代价。通过枚举1号竞选者的最终得票数并调整其他竞选者的得票,实现竞选策略的优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:有 n 个投票人和 m 个竞选者,每个投票人都有初始想投的人(编号从1到m),然而,你可以花费一定代价让一个投票人改变选择,让他投给你指定的人,现在为了保证1号竞选者竞选的成功,它的得票数必须超过其余任何人,求最少需要的代价;

 

分析:n,m<=3000,数据范围比较小,考虑枚举 1 号最终的得票数,我们按照改变每个投票人选择的代价从小到大排序,并且枚举 1 号最终的得票数 k ,则其余竞选人的初始得票数若大于等于k ,则必然要改变他们的选择,让他们的得票数统统小于k;

 

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>

typedef long long ll;
using namespace std;

typedef pair<int,int> P;
const int N = 3005;
 
#define x first
#define y second
P p[N]; 
int n,m;
int tim[N];
int ned[N];

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&p[i].y,&p[i].x);
		tim[p[i].y]++;
	}
	sort(p+1,p+n+1);
	
	ll ans;
	if(tim[1]<=n/2+1) ans=1e17;  //若初始得票数就大于一半,代价就是0
	else ans=0;
	for(int t=tim[1];t<=n/2+1;t++)
	{
		ll sum=0,add=0;
		for(int i=2;i<=m;i++)
		{
			if(tim[i]>=t) ned[i]=tim[i]-t+1,add+=ned[i];  //表示至少需要改变多少初始选择为 i的投票人才能满足条件;
 			else ned[i]=0;
		}
		if(add>t-tim[1]) continue; //如果改变所有初始得票过多的人的数量已经大于当前枚举的1号得票数需要增加的数量就跳过;
		int left=t-tim[1]-add;
		for(int i=1;i<=n;i++)
		{
			if(p[i].y==1) continue;
			if(ned[p[i].y]==0)
			{
		        if(left)
		        {
		        	left--;
		        	sum+=p[i].x;
				}
			}
			else
			{
				ned[p[i].y]--;
				sum+=p[i].x;
			}
		}
		ans=min(ans,sum);
	}
	printf("%lld",ans);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值