CodeForces 589F:Gourmet and Banquet(二分+贪心)

Gourmet and Banquet

Time limit:1000 ms Memory limit:65536 kB OS:Linux


Problem Description

A gourmet came into the banquet hall, where the cooks suggested n dishes for guests. The gourmet knows the schedule: when each of the dishes will be served.

For i-th of the dishes he knows two integer moments in time ai and bi (in seconds from the beginning of the banquet) — when the cooks will bring the i-th dish into the hall and when they will carry it out (ai < bi). For example, if ai = 10 and bi = 11, then the i-th dish is available for eating during one second.

The dishes come in very large quantities, so it is guaranteed that as long as the dish is available for eating (i. e. while it is in the hall) it cannot run out.

The gourmet wants to try each of the n dishes and not to offend any of the cooks. Because of that the gourmet wants to eat each of the dishes for the same amount of time. During eating the gourmet can instantly switch between the dishes. Switching between dishes is allowed for him only at integer moments in time. The gourmet can eat no more than one dish simultaneously. It is allowed to return to a dish after eating any other dishes.

The gourmet wants to eat as long as possible on the banquet without violating any conditions described above. Can you help him and find out the maximum total time he can eat the dishes on the banquet?

Input

The first line of input contains an integer n (1 ≤ n ≤ 100) — the number of dishes on the banquet.

The following n lines contain information about availability of the dishes. The i-th line contains two integers ai and bi (0 ≤ ai < bi ≤ 10000) — the moments in time when the i-th dish becomes available for eating and when the i-th dish is taken away from the hall.

Output

Output should contain the only integer — the maximum total time the gourmet can eat the dishes on the banquet.

The gourmet can instantly switch between the dishes but only at integer moments in time. It is allowed to return to a dish after eating any other dishes. Also in every moment in time he can eat no more than one dish.

Example

Input
3
2  4
1  5
Output
6
Input
3
1  2
1  2
1  2
Output
0

Note

In the first example the gourmet eats the second dish for one second (from the moment in time 1 to the moment in time 2), then he eats the first dish for two seconds (from 2 to 4), then he returns to the second dish for one second (from 4 to 5). After that he eats the third dish for two seconds (from 6 to 8).

In the second example the gourmet cannot eat each dish for at least one second because there are three dishes but they are available for only one second (from 1 to 2).


题意:

一个美食家来吃晚宴,有N个厨师来上菜,每个厨师上菜的时间和收盘子的时间分别是 ai bi ,美食家希望尽可能久地吃菜,同时不冒犯任何厨师,所以美食家吃每道菜的时间都必须要相等(吃一道菜的时间可以不连续),当然美食家每秒只能吃一道菜,问美食家吃菜最长的时间是多少。

解题思路:

对美食家吃一道菜的时间进行二分,设为x,那么输出的答案就是N*x。难点在于如何判断美食家是否能每道菜都吃够x秒的时间。这里用到了贪心的思想,每次先吃收盘子最早的菜,因为其对后面的影响最小,当然每次吃菜的时候不需要一直吃到收盘子,而是吃到x的时间就够了,如果有一道菜吃不够x的时间,就说明x太大,找小的,反之继续找比x大的。为了避免同一时间吃两道菜,用一个vis数组来记录第i秒是否已经用于吃其他菜了。


Code:

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int maxn=105;
int n;
struct Node
{
    int a;
    int b;

} dish[maxn];

int vis[10000+5];

bool cmp(Node x,Node y)
{
    if(x.b==y.b)
        return x.a<y.a;
    return x.b<y.b;
}

bool f(int x)
{
    memset(vis,0,sizeof(vis));
    for(int i=0; i<n; i++)
    {
        int cnt=0;
        for(int j=dish[i].a;j<dish[i].b;j++)
        {
            if(cnt==x)
                break;
            if(!vis[j])
            {
                cnt++;
                vis[j]=1;
            }
        }
        if(cnt<x)
            return false;
    }
    return true;

}

int bs()
{
    int lo=1,hi=10000,ans=0;
    while(lo<=hi)
    {
        int mid=(hi+lo)/2;
        if(f(mid))
        {
            ans=mid;
            lo=mid+1;
        }
        else
            hi=mid-1;
    }
    return ans;
}


int main()
{

    cin>>n;
    for(int i=0; i<n; i++)
    {
        cin>>dish[i].a>>dish[i].b;
    }
    sort(dish,dish+n,cmp);
    cout<<n*bs()<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值