时间管理题解

题目大意

你有n个工作,同一时刻只能做一个任务,其中每个工作有其所需时间及完成的截止时间,问要完成所有工作,最迟要从什么时候开始。你最早可以从时间0开始工作。
输入格式
第一行一个整数n,表示任务数量,接下来M行,每行两个整数,Ti,Si,分别表示该任务的持续时间和截止时间。
输出格式
输出一个整数,表示最晚的开始时间,如果不能完成,输出-1.
样例输入
4
3 5
10 13
5 20
样例输出
2

分析

这道题有两种方法,一种是二分,一种是贪心,先说二分,阅读题目可知答案具有单调性,所以二分l,r,且使得l=-5,若可以完成,则r=mid,否则l=mid,制约条件是l+1

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
struct node{
    int a,b;
}al[100001];
bool cmp(node x,node y){
    if(x.b==y.b) return x.a<y.a;
    return x.b<y.b;
}
int main(){
    int l=-10,r,mid,n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d%d",&al[i].a,&al[i].b),r=max(r,al[i].b);
    sort(al+1,al+1+n,cmp);
    while(l+1<r){
        mid=(l+r)/2;
        int ed=mid,q=1;
        for(int i=1;i<=n;i++){
            if(ed>al[i].b){
                q=0;
                break;
            }
            ed+=al[i].a;
            if(ed>al[i].b){
                q=0;
                break;
            }
        }
        if(q)l=mid;
        else r=mid;
    }
    if(l<0){
        cout<<-1<<endl;
        return 0;
    }
    printf("%d\n",l);
    return 0;
}

再说贪心,贪心的来想,若使开始时间最晚,则要最后一个任务在最最后一刻完成,按任务完成时间降序排序,从后往前推,当发现再某一时间节点时完成不了任务,则输出-1,否则知到推结束,再输出时间节点。
上代码

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
struct node{
    int a,b;
}al[100001];
bool cmp(node x,node y){
    if(y.b==x.b) return x.a<y.a;
    return x.b>y.b;
}
int n,ed=0;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&al[i].a,&al[i].b);
        ed=max(ed,al[i].b);
    }
    sort(al+1,al+1+n,cmp);
    for(int i=1;i<=n;i++){
        if(ed>al[i].b) ed=al[i].b;
        ed-=al[i].a;
        if(ed<0){
            printf("-1\n");
            return 0;
        }
    }
    printf("%d\n",ed);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sjzezwzy/article/details/80898310