LA 4254 Processor (二分 + 贪心)

二分没什么好说的,但 (check) 函数很难写

首先将所有任务按左端点排序,然后枚举时间,速度就是单位时间的工作量

在当前时间之前开始的所有任务中,贪心地先完成结束时间早的任务,使用优先队列来实现

(枚举任务查看时间的写法要处理浮点数,没有通过,不知道是哪里有问题)

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 10010;
const double eps = 1e-11;

int T, n; 

struct Task{
	int r, d, w;
	
	bool operator < (const Task &x) const{
		return d > x.d;
	}
}a[maxn]; 

int maxt, mint;
priority_queue<Task> q; 
bool check(int x){
	while(!q.empty()) q.pop();
	
	int pos = 1;
	for(int i = 1 ; i <= maxt ; ++i){
		if(q.empty()) {
			if(pos > n) return true;
			i = a[pos].r;
		}
		
		while(a[pos].r <= i && pos <= n){
			q.push(a[pos]);
			++pos;
		}
		
		int tmp = x;
		
		while(!q.empty() && tmp > 0){
			Task u = q.top(); q.pop();
			
			if(u.d <= i) return false;	
			
			if(u.w > tmp){
				u.w -= tmp;
				tmp = 0;
				q.push(u);
			} else{
				tmp -= u.w;
			}		
		}
	}
	
	return false;
}

bool cmp(Task x, Task y) { return x.r < y.r || (x.r == y.r && x.d < y.d) ; } 

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(){
	scanf("%d", &T);
	while(T--){
		scanf("%d", &n);
		maxt = 0, mint = 1000000007;
				
		for(int i = 1 ; i <= n ; ++i){
			scanf("%d%d%d", &a[i].r, &a[i].d ,&a[i].w);
			maxt = max(maxt, a[i].d);
			mint = min(mint, a[i].r);
		}
		
		sort(a + 1, a + 1 + n, cmp);
		
		int ans = 0;
		
		int L = 0, R = 100000000;
		while(L <= R){
			int M = L + (R - L) / 2;
//			printf("%d
", M);
			if(check(M)){
				ans = M;
				R = M - 1;
			} else{
				L = M + 1;
			}
		}
		
		printf("%d
", ans);
	}
	return 0;
}

浮点数写法:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 10010;
const double eps = 1e-11;

int T, n; 

struct Task{
	int r, d, w;
	
	bool operator < (const Task &x) const{
		return d > x.d;
	}
}a[maxn]; 

bool check(int x){
	priority_queue<Task> q; 
	
	double t = 0;
	for(int i = 1 ; i <= n ; ){
		int lim = a[i].d;
		t = max((double)a[i].r, t);
		double left = 0;
		
		while(a[i].d <= lim && i <= n){
			q.push(a[i]);
			++i;
		}
		
		while(!q.empty()){
			Task u = q.top();
			
			if(t + eps < (double) u.r){
				left += (double) u.r - t;
				t = (double) u.r;
			}			
			
			if(q.size() == 1){
				left += u.d - t;
				if(left + eps < (double) u.w / x){
					return false;
				}

				t += left - ((double) u.w / x);
				
				q.pop();
				break;
			}
			
			if(t > u.d + eps) return false;
			if(u.d - t + eps < (double) u.w / x){
				return false;
			}
			t += (double) u.w / x;
			q.pop();
		}
	}
	
	return true;
}

bool cmp(Task x, Task y) { return x.r < y.r || (x.r == y.r && x.d < y.d) ; } 

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(){
	freopen("data.in", "r", stdin);
	freopen("ans.out", "w", stdout);
	scanf("%d", &T);
	while(T--){
		scanf("%d", &n);
				
		for(int i = 1 ; i <= n ; ++i){
			scanf("%d%d%d", &a[i].r, &a[i].d ,&a[i].w);
		}
		
		sort(a + 1, a + 1 + n, cmp);
		
		int ans = 0;
		
		int L = 0, R = 100000000;
		while(L <= R){
			int M = L + (R - L + 1) / 2;
			
			if(check(M)){
				ans = M;
				R = M - 1;
			} else{
				L = M + 1;
			}
		}
		
		printf("%d
", ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/tuchen/p/14843518.html