题解:P11457 [USACO24DEC] Job Completion G
xiaoliebao1115 · · 题解
感觉题解区很多都没有证明清楚,自己来一篇题解。
sol
假设有两个工作
那么有
- 如果
sum<=s_i 的话,sum 加上t_i 即可。 - 否则,找到前面已经完成的
t_i 最短的工作记作k ,将他的时间与当前比较,如果当前t 较小则将那个踢掉,当前加入,否则不变。
这样很对,但需要证明将那个踢掉之后一定能加入当前
code
使用优先队列维护即可。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int nn=3e5+5;
int t,n;
struct node{
int s,t;
};
node x[nn];
inline bool cmp(node l1,node l2){
return l1.s+l1.t<l2.s+l2.t;
}
priority_queue<int> q;
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++) cin>>x[i].s>>x[i].t;
sort(x+1,x+n+1,cmp);
int sum=0,ans=0;
for(int i=1;i<=n;i++){
if(sum<=x[i].s){
sum+=x[i].t;
q.push(x[i].t);
ans++;
}
else{
int tmax=q.top();
if(tmax>x[i].t){
q.pop();
sum=sum-tmax+x[i].t;
q.push(x[i].t);
}
}
}
while(!q.empty()) q.pop();
cout<<ans<<endl;
}
return 0;
}