UVALive 4254 二分

题意:t个测试样例,每个测试样例有n个任务,给你起始时间、终止时间和任务量,每个任务必须在起始时间和终止时间之间完成(包括边界),现在要找出一个最小的每分钟处理的任务量,使得可以在规定时间内完成n个任务。


做法:二分,先用优先队列排序,先做已经开始且最早结束的,如果队列非空,判断当前的任务是否在规定的时间,如果不在,那么这个时间就不行。


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
int n;
struct node{
	int l,r,w;
	bool operator <(const node &a)const{
		return r>a.r;//最早结束的放前面 
	}
}e[10005];
priority_queue<node>sp;
bool cmp(node a,node b){
	return a.l<b.l;
}
bool check(int mid){
	int i=0,j=0;
	while(!sp.empty())sp.pop();
	while(1){  
	    while(i<n&&e[i].l<=j)sp.push(e[i++]);//当前的任务到了开始时间 就加入队列  
	    int now=mid;  
	    while(now!=0&&!sp.empty()){//如果当前还能做任务且当前时间的队列非空 就继续做任务 
	        node ita=sp.top();  
	        sp.pop();  
	        int m=min(now,ita.w);  
	        now-=m;  
	        ita.w-=m;  
	        if(ita.w!=0)sp.push(ita);  
	    }  
		    j++;//时间加1 
		    if(!sp.empty()&&sp.top().r<=j)return false;//如果队列非空且任务没有在规定的时间完成 当前答案不可行 
		    if(sp.empty()&&i==n)return true;//如果在规定的时间完成了所有的任务 当前答案可行 
	    }  
}
int main(){
	int t,i,sum;
	scanf("%d",&t);
	while(t--){
		sum=0;
		scanf("%d",&n);
		for(i=0;i<n;i++){
			scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].w);
			sum+=e[i].w;
		}
		sort(e,e+n,cmp);//排序 最早开始的放前面 
		int l=0,r=sum;
		while(l<r){
			int mid=(l+r)>>1;
			if(check(mid)){
				r=mid;
			}
			else l=mid+1;
		}
		cout<<l<<endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值