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;
}