1. 程式人生 > 實用技巧 >[USACO08NOV]時間管理Time Management

[USACO08NOV]時間管理Time Management

題目

Description

Ever the maturing businessman, Farmer John realizes that he must manage his time effectively. He has N jobs conveniently numbered 1..N (1 <= N <= 1,000) to accomplish (like milking the cows, cleaning the barn, mending the fences, and so on).

To manage his time effectively, he has created a list of the jobs that must be finished. Job i requires a certain amount of time T_i (1 <= T_i <= 1,000) to complete and furthermore must be finished by time S_i (1 <= S_i <= 1,000,000). Farmer John starts his day at time t=0 and can only work on one job at a time until it is finished.

Even a maturing businessman likes to sleep late; help Farmer John determine the latest he can start working and still finish all the jobs on time.

作為一名忙碌的商人,約翰知道必須高效地安排他的時間.他有N工作要 做,比如給奶牛擠奶,清洗牛棚,修理柵欄之類的.

為了高效,列出了所有工作的清單.第i分工作需要T_i單位的時間來完成,而 且必須在S_i或之前完成.現在是0時刻.約翰做一份工作必須直到做完才能停 止.

所有的商人都喜歡睡懶覺.請幫約翰計算他最遲什麼時候開始工作,可以讓所有工作按時完成.(如果無法完成全部任務,輸出-1)

Input

* Line 1: A single integer: N

* Lines 2..N+1: Line i+1 contains two space-separated integers: T_i and S_i

Output

* Line 1: The latest time Farmer John can start working or -1 if Farmer John cannot finish all the jobs on time.

Sample Input

4 
3 5 
8 14 
5 20 
1 16 

Sample Output

2 

思路

一道水二分,先按完成時間s[i] 排序;

然後二分開始時間就可以了;‘

程式碼

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline ll read()
{
    ll a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
ll n;
struct ljj
{
    ll t,s;
}a[1010];
inline ll cmp(ljj a,ljj b)
{
    return a.s<b.s;
}
inline ll check(ll x)
{
    for(ll i=1;i<=n;i++)
    {
        x+=a[i].t;
        if(x>a[i].s)
            return 0;
    }
    return 1;
}
int main()
{
    n=read();
    for(ll i=1;i<=n;i++)
    {
        a[i].t=read();
        a[i].s=read();
    }
    sort(a+1,a+n+1,cmp);
    ll l=0,r=a[n].s;
    ll ans=0;
    while(l<=r)
    {
        ll mid=(l+r)>>1;
        if(check(mid))
            l=mid+1,
            ans=max(ans,mid);
        else
            r=mid-1;
    }
    if(ans)
        printf("%lld\n",ans);
    else
        puts("-1");
}

超水二分題,所以就不加什麼解析了