1.先做 b > 0 b>0 b>0的任务,且按照 t t t从小到大的顺序做。
2.对于剩下的 b < 0 b<0 b<0的任务,考虑如何排序做。
设当前时间为 T T T,当前两个任务为: t 1 , b 1 , t 2 , b 2 t_1,b_1,t_2,b_2 t1,b1,t2,b2。
考虑先做任务 1 1 1会导致任务 2 2 2完不成。
T + b 1 < t 2 , T + b 2 > t 1 T+b_1
则 T < t 2 − b 1 , T > t 1 − b 2 T
则 t 1 − b 2 < t 2 − b 1 t_1-b_2
则 t 1 + b 1 < t 2 + b 2 t_1+b_1
说明按照 t + b t+b t+b从大到小排序做任务是最优的。
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
// Problem: P3619 魔法
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3619
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2021-05-09 15:35:01
// --------by Herio--------
#include
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define IOS ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\n",a[n]);
}
struct node{
int t,b;
};
bool cmp1(node &u,node &v){
return u.t<v.t;
}
bool cmp2(node &u,node &v){
return u.t+u.b>v.t+v.b;
}
int main(){
int t;scanf("%d",&t);while(t--){
vector<node>a1,a2;
int n;ll T;scanf("%d%lld",&n,&T);
for(int i=0;i<n;i++){
int t,b;scanf("%d%d",&t,&b);
if(b>=0) a1.pb(node({
t,b}));
else a2.pb(node({
t,b}));
}
sort(a1.begin(),a1.end(),cmp1);
sort(a2.begin(),a2.end(),cmp2);
bool ok = true;
for(int i=0;i<SZ(a1);i++){
if(T>a1[i].t) T+=a1[i].b;
else {
ok = false;
break;
}
}
for(int i=0;i<SZ(a2);i++){
if(T>a2[i].t) T+=a2[i].b;
else {
ok = false;
break;
}
if(T<=0){
ok = false;
break;
}
}
puts(ok?"+1s":"-1s");
}
return 0;
}