Renting Bike 二分

A group of n schoolboys decided to ride bikes. As nobody of them has a bike, the boys need to rent them.

The renting site offered them m bikes. The renting price is different for different bikes, renting the j-th bike costs pj rubles.

In total, the boys’ shared budget is a rubles. Besides, each of them has his own personal money, the i-th boy has bi personal rubles. The shared budget can be spent on any schoolchildren arbitrarily, but each boy’s personal money can be spent on renting only this boy’s bike.

Each boy can rent at most one bike, one cannot give his bike to somebody else.

What maximum number of schoolboys will be able to ride bikes? What minimum sum of personal money will they have to spend in total to let as many schoolchildren ride bikes as possible?

Input
The first line of the input contains three integers n, m and a (1 ≤ n, m ≤ 105; 0 ≤ a ≤ 109). The second line contains the sequence of integers b1, b2, …, bn (1 ≤ bi ≤ 104), where bi is the amount of the i-th boy’s personal money. The third line contains the sequence of integers p1, p2, …, pm (1 ≤ pj ≤ 109), where pj is the price for renting the j-th bike.

Output
Print two integers r and s, where r is the maximum number of schoolboys that can rent a bike and s is the minimum total personal money needed to rent r bikes. If the schoolchildren cannot rent any bikes, then r = s = 0.

Examples
Input
2 2 10
5 5
7 6
Output
2 3
Input
4 5 2
8 1 1 2
6 3 7 5 2
Output
3 8
Note
In the first sample both schoolchildren can rent a bike. For instance, they can split the shared budget in half (5 rubles each). In this case one of them will have to pay 1 ruble from the personal money and the other one will have to pay 2 rubles from the personal money. In total, they spend 3 rubles of their personal money. This way of distribution of money minimizes the amount of spent personal money.

典型的二分+贪心,大体意思是说一群孩子租自行车,每个孩子有自己的一部分钱,除此之外还有一部分公用的钱,自己的钱只能用来租自己的自行车,而公共的钱则用来补自己不足的部分,问这群孩子最多可以租多少辆车以及需要花费多少公共的资金。

先对孩子的钱和自行车租金进行排序,大体思路是有钱的孩子租用贵的车,不够再补,然后利用二分的思想,分别取左为0,右为需要的自行车数,这里右一开始取的是自行车数和孩子中的最小值,意思是如果车比人多,那么假定一开始一人一辆可以满足,如果车比人少,那么最多也就只能租那么多车,所以右值为两者里的最小值。在进行二分的过程中,通过比较mid左侧的值,如果左侧的也就是所有人里面钱少的一部分人如果需要公共资金的和小于公共资金总额,说明当前方案可行,于是调整左值,表示这一部分人就租这部分车了,如果大于了总额,说明这些人里面有的人租不了车,必然总的车数要减少,于是调整右值,直到调整完成为止,最后的右值即是总的自行车数,去最便宜的右值量自行车,求费用和减去公共资金就是最后答案。

额外注意一下数据量的问题,并不是所有量都可以直接用int。

AC代码:

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int peo[100005];
long long int pri[100005];
int n,m;
long long int a;
int check(int mid)
{
	long long int sum=0;
	for(int i=0;i<mid;i++)
		if(pri[mid-i-1]>peo[n-i-1])
			sum+=pri[mid-i-1]-peo[n-i-1];
	if(sum>a) return 0;
	return 1;
}
int main()
{
	cin>>n>>m>>a;
	for(int i=0;i<n;i++)
		cin>>peo[i];
	for(int i=0;i<m;i++)
		cin>>pri[i];
	sort(peo,peo+n);
	sort(pri,pri+m);
	int l=0,r=min(n,m);
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(check(mid))
			l=mid+1;
		else
			r=mid-1;
	}
	long long int sum=0;
	for(int i=0;i<r;i++)
		sum+=pri[r-1-i];
	sum = max(0LL, sum-a);
	cout<<r<<" "<<sum<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43849505/article/details/87462275