因为每增加一个订单,时间是会增加的,所以先按截止时间d排序,
这样的话无论是删除一个订单,或者增加订单,都不会影响已经选好的订单。
然后维护一个已经选好的订单的大根堆(优先队列),如果当前无法选择的话,
那么尝试和之前花费时间最长的交换。如果qi<qj的话,交换之后花费的时间更短且截止时间di更长,情况不会比没交换更糟·。
#include<bits/stdc++.h> using namespace std; const int maxn = 8e5+5; struct Cus { int q,d; bool operator < (const Cus& x) const { return q < x.q; } }P[maxn]; bool cmp(const Cus& x, const Cus& y) { return x.d < y.d; } priority_queue<Cus> Q; int main() { //freopen("in.txt","r",stdin); int T; scanf("%d",&T); while(T--){ int n; scanf("%d",&n); for(int i = 0; i < n; i++) scanf("%d%d",&P[i].q,&P[i].d); sort(P,P+n,cmp); int cur = 0; for(int i = 0; i < n; i++){ if(P[i].q + cur <= P[i].d) Q.push(P[i]), cur += P[i].q; else { if(Q.size() && P[i].q < Q.top().q ) { cur += P[i].q - Q.top().q; Q.pop(); Q.push(P[i]); } } } printf("%d ",Q.size()); while(Q.size()) Q.pop(); if(T) putchar(' '); } return 0; }