链接:http://codeforces.com/problemset/problem/363/D

题解:

363D - Renting Bikes

k boys to rent bikes. If some k boys can rent a bike, then the k "richest" boys (with the most amount of personal money) also can do that. It is easy to see that if they can rent bikes, they can rent k cheapest bikes (if we first sort the bikes in increasing order of price, it will be just the first k

k richest boys and try to match them with k cheapest bikes, spending as much common budget as possible. The following algorithm works (try to understand and prove it before asking questions): take the boy with least number of money (of course, among the considered k richest) and try to give him the cheapest bike. If the boy has ehough personal money to rent this bike, use his money to do this. Otherwise, use all his money and take some money from the common budget. Continue this process with the second cheapest bike and the second "poorest among the richest" boys. This process can end in two ways: we will either run out of budget and fail to rent kbikes, or we will successfully rent these bikes.

好牛的二分。。涨知识了。。

代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
#define ll __int64
int i,j;
int n,m,k;

int a[100100];
ll b[100100];

ll sum,money;
bool check(int p)
{
	int i=0;
	sum=0;
	money=k;
	int pb=1,pa=n-p+1;
	while(i!=p)
	{
		if(a[pa]>=b[pb])
			sum+=b[pb];
		else
		{
			if(money>=b[pb]-a[pa])
			{
				money-=b[pb]-a[pa];
				sum+=a[pa];
			}
			else
				return 0;
		}
		pa++;
		pb++;
		i++;
	}
	return 1;
}

int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for(i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(i=1;i<=m;i++)
		scanf("%I64d",&b[i]);
	sort(a+1,a+n+1);
	sort(b+1,b+m+1);
	int l=0,r=min(n,m);
	while(l<r)
	{
		int mid=(r+l+1)/2;
		if(check(mid))
			l=mid;
		else
			r=mid-1;
	}
	ll tt=0;
	for(i=1;i<=l;i++)
		tt+=b[i];
	tt-=k;
	if(tt<=0) tt=0;
	printf("%d %I64d\n",l,tt);
}