cf#211-D. Renting Bikes-二分

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

题意:

n个人,每个人b[i]块钱

m辆车,每辆车租金p[i]块钱

A,共用资金

共用资金可以给任何人租单车,但是个人的钱只能给自己用

每个人最多买一辆单车,


假设最多能买R辆车,求出R

在买R辆车的前提下,尽可能少用个人的钱,输出这个最少的个人花费S


煞笔贪心了一发。。。

显然直接枚举答案即可,Left=0,Right=min(n,m)

然后当能买X辆车时,我们让最有钱的X个人去买最便宜的X辆车,再加上共用资金,如果能买则OK,否则NOT

二分得到答案R

得到答案R后,要花最少钱肯定是买最便宜的R辆车啦。。。。sum=p[1]~p[R],

A》sum则 个人花费为0,否则为 sum-A

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;

__int64 b[100005];
__int64 p[100005]; 
__int64 tmp[100005];
__int64 vis[100005];
__int64 res[100005];

__int64 min(__int64 a,__int64 b)
{return a<b?a:b;}
__int64 cun=0;
__int64 n,m,a; 
bool  cmp(__int64 a,__int64 b)
{return a>b;}
__int64 bin(   )
{
	__int64 sum=0;
	__int64 i;
	for (i=1;i<=cun;i++)
	{
		sum+=p[i];
	}  
	if (a>=sum)return 0;
	else
		return (sum-a);
	
}
__int64 ok(__int64 x)
{
	__int64 i;
	__int64 j=x;
	__int64 need=0;
	for (i=1;i<=x;i++)
	{
		if (b[i]>=p[j])
			need+=0;
		else
			need+=p[j]-b[i];
		j--;
	}
	if (a>=need) return 1;
	else
		return 0; 
}
int main()
{
	
	__int64 i,j; 
	scanf("%I64d%I64d%I64d",&n,&m,&a);
	__int64 tmpa=a;
	for (i=1;i<=n;i++)
		scanf("%I64d",&b[i]);
	sort(b+1,b+1+n,cmp);
	
	
	for (i=1;i<=m;i++)
		scanf("%I64d",&p[i]);
	sort(p+1,p+1+m);
	
	
	__int64 l=0;
	__int64 r=min(n,m);
	while(l<=r)
	{
		if (r-l<=1)
		{
			if (ok(r))
				cun=r;
			else
				cun=l;
			break;
		}
		__int64 mid=(l+r)>>1;
		if (ok(mid))
			l=mid;
		else
			r=mid-1; 
	}  
	if (cun==0)
	{
		printf("0 0\n"); 
		return 0;
	} 
	a=tmpa;
	printf("%I64d %I64d\n",cun,bin());
	   return 0;
	   
}


你可能感兴趣的:(cf#211-D. Renting Bikes-二分)