1. 程式人生 > 實用技巧 >【CF1443C】The Delivery Dilemma 題解

【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]\n",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\n",ans);
    }
    return 0;
}