codeforces 1250B The Feast and the Bus 枚举+贪心

http://codeforces.com/problemset/problem/1250/B
Employees of JebTrains are on their way to celebrate the 256-th day of the year! There are n employees and k teams in JebTrains. Each employee is a member of some (exactly one) team. All teams are numbered from 1 to k. You are given an array of numbers t1,t2,…,tn where ti is the i-th employee’s team number.

JebTrains is going to rent a single bus to get employees to the feast. The bus will take one or more rides. A bus can pick up an entire team or two entire teams. If three or more teams take a ride together they may start a new project which is considered unacceptable. It’s prohibited to split a team, so all members of a team should take the same ride.

It is possible to rent a bus of any capacity s. Such a bus can take up to s people on a single ride. The total cost of the rent is equal to s⋅r burles where r is the number of rides. Note that it’s impossible to rent two or more buses.

Help JebTrains to calculate the minimum cost of the rent, required to get all employees to the feast, fulfilling all the conditions above.

Input
The first line contains two integers n and k (1≤n≤5⋅105,1≤k≤8000) — the number of employees and the number of teams in JebTrains. The second line contains a sequence of integers t1,t2,…,tn, where ti (1≤ti≤k) is the i-th employee’s team number. Every team contains at least one employee.

Output
Print the minimum cost of the rent.

Examples
Input
6 3
3 1 2 3 2 3
Output
6
Input
10 1
1 1 1 1 1 1 1 1 1 1
Output
10
Input
12 4
1 2 3 1 2 3 4 1 2 1 2 1
Output
12

题目大意:有 n n n个人, a i a_i ai表示第 i i i个人属于第 a i a_i ai个队伍,一共有 k k k个队伍,保证每个队伍至少有 1 1 1个人,现在有一辆班车,它可以承载的乘客数量是任意的,假设这个值为 S S S,你每次可以选择拉走一个队伍或者两个队伍(必须是完整的),假设一共需要 R R R次才能把全部队伍拉走,那么花费就是 S ∗ R S*R SR,求花费的最小值。

思路:这题是不能二分的,因为 S ∗ R S*R SR显然不是一个单调函数。又因为 k k k的范围比较小,不难想到枚举的做法,其实这道题涉及到了一个经典贪心问题:我们把 k k k个队伍按照人数从大到小排列,因为最多只能拉走两个队伍,所以可以设 l = 1 , r = k l=1,r=k l=1,r=k,每次都尽量把 l 、 r l、r lr凑到一起拉走,这样在 S S S确定时可以保证 R R R是最小的。现在思考怎么确定枚举的范围,排完序后我们有: b 1 > = b 2 > = … … > = b k b_1>=b_2>=……>=b_k b1>=b2>=>=bk,那么 S S S的最小值一定是 b 1 b_1 b1,考虑贪心的过程,我们不断的想把 l 、 r l、r lr凑到一起,那么最大值一定要从这些值中取得: ( a 1 + a k , a 2 + a k − 1 , … … ) (a_1+a_k,a_2+a_{k-1},……) (a1+ak,a2+ak1,),你可能会问为什么没有 a 2 + a k a_2+a_k a2+ak呢,因为显然这些值都小于 a 1 + a k a_1+a_k a1+ak,最大值也确定了,就可以枚举了。

#include
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;

int a[8005];
int n,k;

int main()
{
	scanf("%d %d",&n,&k);
	int u;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&u);
		++a[u];
	}
	sort(a+1,a+1+k,greater<int>());
	int MAX=0;
	for(int i=1,j=k;i<=j;i++,j--)
	{
		if(i!=j)
			MAX=max(MAX,a[i]+a[j]);
		else
			MAX=max(MAX,a[i]);
	}
	ll ans=1e16;
	for(int s=a[1];s<=MAX;s++)
	{
		int l=1,r=k;
		int times=0;
		while(l<=r)
		{
			++times;
			if(l!=r&&a[l]+a[r]<=s)
				++l,--r;
			else
				++l;
		}
		ans=min(ans,times*1ll*s);
	}
	printf("%lld\n",ans);
}

你可能感兴趣的:(暴力,贪心,比赛补题)