CodeForces - 589F

Gourmet and Banquet

Time limit : 2000 ms Memory limit : 524288 kB

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.

Examples

input
3
2 4
1 5
6 9
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).


題目大意:
有一個人去宴會廳品嚐各道菜餚,他在每道菜上面花費相同的時間。不過每道菜的開放時間有限,有各自的開始時間與結束時間。
如果不考慮從一道菜到另一道菜的時間,問這個人最多能花多久時間。

解題思路:
1.用二分搜索的方式,去枚舉每道菜最多能品嚐多久,最大的總時間就是每道菜花費的時間乘以菜的數量。
2.採取貪心策略,優先去品嚐結束時間早的,結束時間相同的優先品嚐開始時間晚的。

struct Node {
    int start, end;
    bool operator < (const Node& n) const   {
        return end < n.end || ((end == n.end) && (start < n.start));
    }
};

3.將所有的時間看成一段一段的單位時間,用一個bool數組表示這個單位時間有沒有在品嚐其他菜。按照之前的貪心策略依次去品嚐
菜餚。在菜餚開放的時間內依次選取空閒的時間,如果遍歷完開放時間,發現能選取的時間沒能超過mid,則mid值過大不可行。

核心代碼:

bool test(int x) {
    memset(visit, 0, sizeof(visit));      //測試前,先將時間段全部置爲空閒
    int fin;
    for (int i = 0; i < num; i++) {
        fin = 0;
        for (int j = q[i].start; j < q[i].end; j++) {
            if (!visit[j]) {
                visit[j] = 1;
                if (++fin == x)            //已經選夠了時間,進入下一道菜
                    break;
            }
        }
        if (fin < x)                        //遍歷完菜餚的全部開放時間,沒有足夠時間,x值過大。
            return false;
    }
    return true;
}

4.選取了足夠多的時間,達到mid後立刻跳出,進入下一道菜的測試。直到所有的菜都通過測試,則mid值可行。


源代碼

#include<iostream>
#include<stdio.h>
#include<vector>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<sstream>
using namespace std;

struct Node {
    int start, end;
    bool operator < (const Node& n) const   {
        return end < n.end || ((end == n.end) && (start < n.start));
    }
};
Node q[10005];
bool visit[10005];
int num;

bool test(int x) {
    memset(visit, 0, sizeof(visit));
    int fin;
    for (int i = 0; i < num; i++) {
        fin = 0;
        for (int j = q[i].start; j < q[i].end; j++) {
            if (!visit[j]) {
                visit[j] = 1;
                if (++fin == x)
                    break;
            }
        }
        if (fin < x)
            return false;
    }
    return true;
}

 int main() {
     int i;
     scanf("%d", &num);
     for (i = 0; i < num; i++) {
         scanf("%d%d", &q[i].start, &q[i].end);
     }
     sort(q, q + num);
     int l = 1, r = 100001;
     while (l<r - 1)     {
         int mid = (l + r) >> 1;
         if (test(mid))
             l = mid;
         else  
             r = mid;
     }
     if (test(l))
         printf("%d\n", l*num);
     else
         printf("0\n");
     return 0;
}
發佈了30 篇原創文章 · 獲贊 14 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章