POJ 1716 Integer Intervals

 

Integer Intervals
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 7116   Accepted: 2852

Description

An integer interval [a,b], a < b, is a set of all consecutive integers beginning with a and ending with b. 
Write a program that: finds the minimal number of elements in a set containing at least two different integers from each interval.

Input

The first line of the input contains the number of intervals n, 1 <= n <= 10000. Each of the following n lines contains two integers a, b separated by a single space, 0 <= a < b <= 10000. They are the beginning and the end of an interval.

Output

Output the minimal number of elements in a set containing at least two different integers from each interval.

Sample Input

4
3 6
2 4
0 2
4 7

Sample Output

4

Source

CEOI 1997

 

 /*
贪心算法:

先对所有区间按照左端点非降序排序,然后依次处理每个区间,total表示需要的总的点数,期间

用curF, curT分别表示在当前最优情况下,上一个区间取的两个最靠右侧的端点,即curF和curT

可以覆盖当前区间且都不能再往右边挪动了,那么对于下一个区间seg[f, t]按照如下情况处理

(1)f  > curT

        则curF,curT不能覆盖当前区间,对于当前区间需要增加两个点分别为 curF = t -1, curT = t,即尽量往右取

(2)f <= curT && f > curF,由于curF不能再往右边挪动寻找替换点,因此需要增加一个点:

              a. 若curT >= t,增加新点 curF = t - 1,将curT挪到t代替原来的curT

              b.若curT < t,用curT代替curF, 增加新点 curT = t

(3)f < curT ,由于上一个区间的左端点肯定位于当前区间左端点的非右侧,所以肯定可以通过挪动curF来为当前区间所用而不影响前一个区间,同理如果需要肯定可以通过挪动curT来为当前区间所用而不影响前一个区间

              a. t <= curF, 挪动curF为t-1,挪动curT为t

              b. curF < t <= curT,curF不用动,挪动curT到t

              c. t > curT,curF, curT均不用替换

*/
#include <iostream> #include <algorithm> #define MAX_N 10000 using namespace std; struct seg { int from, to; }segs[MAX_N + 1]; int n; bool compare(const seg &s1, const seg &s2) { if(s1.from < s2.from) return true; else if(s1.from == s2.from) return s1.to <= s2.to; else return false; } int main() { int i; scanf("%d", &n); for(i = 1; i <= n; i++) scanf("%d%d", &segs[i].from, &segs[i].to); sort(&segs[1], &segs[1] + n, compare); //curF, curT保存取到的最后两个点,初始状态下取第一个seg倒数第二和第一个元素 int curF = segs[1].to - 1, curT = segs[1].to, total = 2; for(i = 2; i <= n; i++) { int newF = curF, newT = curT; //当新段和最后两个点完全不相交 if(segs[i].from > curT) { //取新点,同样尽量往后取 total += 2; newT = segs[i].to; newF = newT - 1; } //curF被超越 else if(segs[i].from > curF) { //此时需要取一个新点 total++; //当前段终点小于curT时,只需取新点segs[i].to - 1作为curF,并将curT平移至segs[i].to(没有加新点,只是做替换) if(curT >= segs[i].to) newF = segs[i].to - 1; //否则将curT作为新的curF并取新点segs[i].to(尽量往后取) else newF = curT; newT = segs[i].to; } //当segs[i].from <= curF时,说明curF仍然可用,不用取新点 else { if(segs[i].to <= curF) //判断是否需要将curT平移至segs[i].to { newF = segs[i].to - 1; newT = segs[i].to; } else if(segs[i].to < curT) newT = segs[i].to; } curF = newF; curT = newT; } printf("%d/n", total); return 0; } 

 

你可能感兴趣的:(POJ 1716 Integer Intervals)