贪心:最大相交区间

来源:互联网 发布:决战武林进阶数据亲 编辑:程序博客网 时间:2024/05/01 23:55

题目:http://acm.zcmu.edu.cn/JudgeOnline/problem.php?id=1892

这题快搞疯我了,一开始以为直接排序然后取相邻,后来发现不行。
在询问了大佬之后大佬给讲了一下,茅塞顿开,顿时觉得我可能长了个假脑。

在找两组的时候,即k = 2时,排序区间左端点,维护最大区间右端点,有以下递推式:

第i个区间[a,b]:ans = max(ans, min(maxr, b) - a + 1);maxr = max(maxr, b);

同样的,当k可以去任意数时,我们只需要将维护最大区间右端点改成维护第k - 1大区间右端点即可
维护方法:用小根堆维护k - 1个数,如果新的区间右端点比小根堆堆顶元素要大,那就交换一下再维护一下小根堆

然后vs上的max和min貌似用不了,就手写了一个

有思路以后又wa了一次,原因是我在最后输出ans + 1,没有考虑到答案为0(区间都不重复)的情况
改了以后又RE了,原因是没有考虑到k == 1的情况即small.top()不存在,于是加上了判断k == 1
然后就喜闻乐见的超时了。。。手打的快排竟然撑不过300000。。。我也是ri le gou le。。。
学了一下sort的结构体用法以后,终于ac了。。。

代码如下:

#include <iostream>#include <cstdio>#include <algorithm>        //sort#include <queue>            //根堆#include <functional>       //小根堆里的greater<int>using namespace std;struct RULER {    int x;    int y;}ruler[400000] = { 0 };int max(int a, int b)       //vs上的max和min貌似用不了{    return a > b ? a : b;}int min(int a, int b){    return a < b ? a : b;}bool comparison(struct RULER l, struct RULER r)     //结构体排序的参数{    return l.x < r.x;}/*void Sort(int l, int r)           //一开始手打排序,结果莫名其妙才300000就超时了...{    if (l >= r)        return;    int pivot = ruler[l].x;    int pivotors = l;    for (int i = l + 1; i <= r; i++)    {        if (ruler[i].x < pivot) {            pivotors++;            swap(ruler[pivotors], ruler[i]);        }    }    swap(ruler[l], ruler[pivotors]);    Sort(l, pivotors - 1);    Sort(pivotors + 1, r);}*/int main(){    int n, k;    cin >> n >> k;    for (int i = 0; i < n; i++)        scanf("%d%d", &ruler[i].x, &ruler[i].y);    sort(ruler, ruler + n, comparison);    priority_queue<int, vector<int>, greater<int> > small;    for (int i = 0; i < k - 1; i++)        small.push(ruler[i].y);    int ans = 0, maxr;    //maxr = small.top();   没有考虑k == 1的情况    if (k == 1)        maxr = 2000000000;    else        maxr = small.top();    for (int i = k - 1; i < n; i++) {        ans = max(ans, min(maxr, ruler[i].y) - ruler[i].x + 1);        if (ruler[i].y > maxr) {            small.pop();            small.push(ruler[i].y);            maxr = small.top();        }    }    cout << ans << endl;    return 0;}

顺便给自己做个关于根堆和快排的笔记:

priority_queue<int>     //xxx 大根堆   #include <queue>priority_queue<int, vector<int>, greater<int>>  //xxxx 小根堆  #include <queue> #include <functional>xxx.top()   //访问最值xxx.push()  //插入最值(插入后自动维护)xxx.pop()   //删除最值(删除后自动维护)
#include <algorithm>bool comparison(struct RULER l, struct RULER r){    return l.x < r.x;   //从小到大}sort(ruler, ruler + n, comparison);

顺便贴一下一个相似题的一解题报告:http://blog.csdn.net/chj_zmr/article/details/8800313

最后感谢一下那个教我题大佬顺便膜一发orz

0 0