codeforces 458C Elections

C. Elections
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

Sample test(s)
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个投票者,告诉他想投给谁和你贿赂他的钱要让自己选举成功就要让支持自己的人严格大于其他人。0号是自己。求最少需要贿赂多少钱才能使自己当选。

思路:三分答案。因为该题没有单调性,即要让其他所有人小于一个给定值而自己大于该给定值,这个给定值不是越大贿赂的钱越多或越少。

但这是一个凸性函数,所以可三分。

代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
//#pragma comment(linker, "/STACK:102400000,102400000")
typedef  long long ll;
#define INF 1e9
#define MAXN 21
#define maxn 100005
const ll mod = 1LL<<32;
#define eps 1e-7
#define pi 3.1415926535897932384626433
#define rep(i,n) for(int i=0;i a[maxn];
vector v;
ll Cost(int h)
{
	ll res = 0,need = h - a[0].size();
	v.clear();
	for(int i = 1;i < maxn - 1; i++)
	{
		for(int j = 0;j < a[i].size(); j++)
		{
			if(a[i].size() - j >= h)
			{
				need --;
				res += a[i][j];
			}
			else
			{
				v.push_back(a[i][j]);
			}
		}
	}
	sort(v.begin(),v.end());
	rep(i,need) res += v[i];
	return res;
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	//  freopen("out.txt","w",stdout);
#endif
	int n;
	while(~scanf("%d",&n))
	{
		rep(i,maxn) a[i].clear();
		rep(i,n)
		{
			int u;
			ll c;
			scanf("%d%lld",&u,&c);
			a[u].push_back(c);
		}
		rep1(i,maxn-2) sort(a[i].begin(),a[i].end());
		int l = a[0].size(), r = n;
		while(l + 2 < r) //三分,整数易产生误差,一般留下2的范围进行特判
		{
			int q1, q2;
			q1 = (l+r)/2;
			q2 = (r+q1)/2;
			if(Cost(q1) > Cost(q2)) l = q1;
			else r = q2;
		}
		ll ans = INF;
		for(int i = l;i <= r; i++) {
			ans = min(ans,Cost(i));
		}
		cout<



你可能感兴趣的:(三分)