codeforces 1443C - The Delivery Dilemma (贪心 + 优先队列)
题目链接:https://codeforces.com/problemset/problem/1443/C
贪心
首先,如果配送时间少于自己取的时间,则肯定选择配送
其次,第一步中的配送时间中有一个最大值 \(M\), 而所有配送时间少于 \(M\) 的店家都可以选择配送, 将剩下的
配送时间丢进一个小根堆里
最后,把所有剩下的店家自己取的时间加起来得到 \(SUM\), 如果 \(SUM\) 比小根堆的堆顶大,则选择堆顶的店家配送,
一定比当前更优,然后更新一下最大时间,直到 \(SUM\) 小于堆顶,此时即为最优答案
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<ll, int> P;
const int maxn = 200010;
int T, n;
ll a[maxn], b[maxn];
priority_queue<P, vector<P>, greater<P> > Q;
ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
int main(){
T = read();
while(T--){
while(!Q.empty()) Q.pop();
n = read();
for(int i = 1 ; i <= n ; ++i) b[i] = read();
for(int i = 1 ; i <= n ; ++i) a[i] = read();
ll suma = 0, sumb = 0, time = 0;
for(int i = 1 ; i <= n ; ++i){
if(a[i] >= b[i]) time = max(time, b[i]);
}
for(int i = 1 ; i <= n ; ++i){
if(b[i] > time){
suma += a[i];
Q.push(make_pair(b[i], i));
}
}
if(time >= suma){
printf("%lld\n", time);
} else{
while(!Q.empty()){
P p = Q.top();
if(suma >= p.first){
time = max(time, p.first);
suma -= a[p.second];
Q.pop();
} else break;
}
time = max(time, suma);
printf("%lld\n", time);
}
}
return 0;
}