【CF1443C】The Delivery Dilemma 题解

原题链接

题意简介

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;
}
原文地址:https://www.cnblogs.com/Qing-LKY/p/CF1443C-solution.html