题意简介
Petya 想从 n 家餐馆点菜。他可以选择点后让它们送过来,也可以自己过去拿回来。
已知,每家餐馆送过来需要的时间为 (a_i) ,他自己去拿的时间为 (b_i) 。
而且餐馆送菜是同时开始的,而自己去拿得一个一个走。(就是说 (a_i) 取 max,(b_i) 取 sum)
现在,Petya 想知道自己至少要多久的时间才能拿到所有的菜。
思路分析
一眼看出二分。
首先,答案有个很明显的上界:(max{a_i})
而且判断 x 是否符合要求的方式也非常简单,对于 (a_i>x) 的所有餐馆只能走过去拿,于是把这些餐馆的 (sum b_i) 求出来后判断其是否小于等于 x 就行了。
需要注意的是答案不一定是 (a_i) 中的某个数,我一开始就因为这个傻逼原因 wa 了一发。
代码库
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <queue>
using namespace std;
typedef long long ll;
#define REG register
#define rep(i,a,b) for(REG int i=a;i<=b;i++)
#define Rep(i,a,b) for(REG int i=a;i>=b;i--)
inline ll scan(){
REG ll x=0,f=1; REG char ch=0;
while(ch<'0'||ch>'9') ch=='-'&&(f=-1),ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*f;
}
const ll N=2e5+5,mod=1e9+7;
ll n;
struct node{
ll a,b;
node(int x=0,int y=0):a(x),b(y){}
}A[N];
bool cmp(node A,node B){
return A.a<B.a;
}
bool check(ll x){
ll sum=0;
rep(i,1,n){
if(A[i].a>x){
sum+=A[i].b;
}
}
//printf("%lld %lld]
",A[d].a,sum);
return sum<=x;
}
int main(){
ll t=scan();
while(t--){
n=scan();
rep(i,1,n) A[i].a=scan();
rep(i,1,n) A[i].b=scan();
sort(A+1,A+1+n,cmp);
ll maxn=A[n].a;
ll l=1,r=maxn,mid,ans=-1;
while(l<=r){
mid=(l+r)>>1;
if(check(mid)) r=mid-1,ans=mid;
else l=mid+1;
}
printf("%lld
",ans);
}
return 0;
}