zoukankan      html  css  js  c++  java
  • 【算法学习笔记】51. 贪心法 区间排序问题 SJTU OJ 1360 偶像丁姐的烦恼

    Description

    成为LL冠军的人气偶像丁姐最近比较烦,许多商业活动找上门来。因为每次商业活动给的毛爷爷都一样,所以丁姐希望能够尽可能多的参加这些活动。然而,商业活动的起止时间并不由丁姐说了算,因此丁姐想写一个程序,求出他最多能够参加的商业活动的数量。

    Input Format

    第一行一个数n,表示可选活动的数量。

    接下n行每行两个数,表示每个活动开始时间t1_i和结束的时间t2_i。

    Output Format

    一个数字,表示丁姐最多能够参加的活动的数量。

    Sample Input

    10
    0 3
    0 5
    10 13
    12 15
    2 6
    4 8
    9 11
    13 18
    14 16
    15 20
    

    Sample Output

    5
    

    Hint

    样例选取的活动时间为:(0, 3), (4, 8), (9, 11), (12, 15), (15, 20)

    n≤100000

    0≤t1_i<t2_i≤1000000

     
     
     
     
    思路1.按左端排序 (同左则按右)
    错误代码如下:
    #include <iostream>
    #include <algorithm>
    using namespace std;
     
    struct Period
    {
        int start;
        int end;
    };
     
    //按照start排序
    int cmp_period(const void* _a, const void* _b){
        Period* a = (Period*) _a;
        Period* b = (Period*) _b;
        if((*a).start != (*b).start)
            return (*a).start - (*b).start;
           else
            return (*a).end - (*b).end;
    }
     
    Period ps[100001];
     
    int main(int argc, char const *argv[])
    {
        
        int n;
        cin>>n;
        for (int i = 0; i < n; ++i){
            
            cin>>ps[i].start>>ps[i].end;
        }
        
        qsort(ps,n,sizeof(Period),cmp_period);
        
        // for (int i = 0; i < n; ++i)
        // {
        //     cout<<ps[i].start<<" "<<ps[i].end<<endl;
        // }
        
        int cur = ps[0].start;
        int index = 0;
        int ans = 1;
        while(1){
            cur = ps[index].end;
            index++;
            for(;index < n; index++){
                if(ps[index].start >= cur){
                    if(index<n-1 and ps[index+1].end < ps[index].end)
                        index++;
                    ans++;
                    break;
                }
            }
            if(index >= n-1)
                break;
        }
        cout<<ans<<endl;
        return 0;
    }
    错误代码1
    样例经过排序后则是
    0 3
    0 5
    2 6
    4 8
    9 11 
    10 13
    12 15
    13 18
    14 16
    15 20
     
    第一直觉是先选择第一个区间,然后选择左端点大于等于第一个区间右端点的第一个区间,(4,8) 然后以此类推。因为同样的起点里,肯定选择的是尾部更小的。
    但是这种方法会产生一个问题就是,遇到了完全重合区间没有办法延伸。
    比如
    0 3
    3 9
    4 8
    8 9
    按刚才的算法回选择 0 3, 3 9 但是实际上应该是 0 3, 4 8, 8 9
    原因在于4,8是完全含于3,9的,所以我们要选择4,8并继续进行下去
     
  • 相关阅读:
    c/c++混编
    inotify监听文件
    二维数组
    CentOS7 修改系统时间
    书签书签
    c语言并行程序设计之路(四)(barrier的实现和条件变量)
    MPI分布式内存编程(一):预备知识
    有些狮子不喝咖啡:条件式与合取式的翻译
    【部分博客已搬家至博客园】对CSDN、博客园和简书的一点比较
    c语言并行程序设计之路(三)(信号量与同步)
  • 原文地址:https://www.cnblogs.com/yuchenlin/p/sjtu_oj_1360.html
Copyright © 2011-2022 走看看