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;
}
posted @ 2020-11-18 23:05  Tartarus_li  阅读(240)  评论(0编辑  收藏  举报