P3619 魔法(贪心&排序)

P3619 魔法(贪心&排序)

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_1t_1 T+b1<t2,T+b2>t1

​ 则 T < t 2 − b 1 , T > t 1 − b 2 Tt_1-b_2 T<t2b1,T>t1b2

​ 则 t 1 − b 2 < t 2 − b 1 t_1-b_2t1b2<t2b1

​ 则 t 1 + b 1 < t 2 + b 2 t_1+b_1t1+b1<t2+b2

说明按照 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;
}

你可能感兴趣的:(P3619 魔法(贪心&排序))