• (学习10)贪心算法之相容问题


    问题描述

    相容问题:有一个礼堂需要用于举办活动,每个活动有开始时间与结束时间;如果任何两个活动不能在礼堂中同时进行,问如何选择这些活动,使得能在礼堂中安排最多活动;

    解析:

    贪心策略1:活动按照结束时间进行升序排序:

    从第一个活动开始向后选择,若当前活动与前一个活动相容(fi-1<=si)

    活动序号 i

    1

    2

    3

    4

    5

    6

    开始时间si

    1

    2

    2

    4

    6

    8

    结束世界fi

    2

    3

    4

    6

    12

    12

    选择活动1:这是结束最早的活动

    选择活动2:因为s2==f1,与活动1相容,即纳入安排

    不选择活动3:因为s3<f2,与活动2不相容,所以不纳入安排

    选择活动4:因为s4>f2,与活动2相容,所以纳入安排

    选择活动5:因为s5>f4,与活动4相容,所以纳入安排

    选择活动6:因为s6<f5,与活动5相容,所以纳入安排

     策略一在这个问题上被证明是可行正确的,具体证明较为复杂,可以自行研究

    贪心策略2:按照开始时间进行排序:

    活动序号 i

    1

    2

    3

    4

    5

    6

    开始时间si

    1

    2

    2

    4

    6

    8

    结束世界fi

    2

    3

    4

    6

    12

    12

    选择活动1:这是结束最早的活动

    选择活动2:因为s2==f1,与活动1相容,即纳入安排

    不选择活动3:因为s3<f2,与活动2不相容,所以不纳入安排

    选择活动4:因为s4>f2,与活动2相容,所以纳入安排

    选择活动5:因为s5>f4,与活动4相容,所以纳入安排

    不选择活动6:因为s6<f5,与活动5不相容,所以不纳入安排

     

     

    反例:

    活动序号 i

    1

    2

    3

    4

    5

    6

    7

    开始时间si

    1

    1

    2

    2

    4

    5

    6

    结束世界fi

    2

    3

    3

    4

    7

    6

    8

     

    而最优策略:

    活动序号 i

    1

    2

    3

    4

    5

    6

    7

    开始时间si

    1

    1

    2

    2

    4

    5

    6

    结束世界fi

    2

    3

    3

    4

    7

    6

    8

     

     

    贪心策略3:按照活动时间进行排序:

    活动序号 i

    1

    2

    3

    4

    5

    6

    开始时间si

    1

    2

    2

    4

    8

    6

    结束世界fi

    2

    3

    4

    6

    12

    12

     

    选择活动1:这是活动时间最少的活动

    选择活动2:因为s2==f1,与活动1相容,即纳入安排

    不选择活动3:因为s3<f2,与活动2不相容,所以不纳入安排

    选择活动4:因为s4>f2,与活动2相容,所以纳入安排

    选择活动5:因为s5>f4,与活动4相容,所以纳入安排

    不选择活动6:因为s6<f5,与活动5不相容,所以不纳入安排

     

    贪心策略3反例:

    活动序号 i

    1

    2

    3

    开始时间si

    7

    4

    8

    结束世界fi

    9

    8

    14

     

    而最优策略:

     

    活动序号 i

    1

    2

    3

    开始时间si

    7

    4

    8

    结束世界fi

    9

    8

    14

     

    针对策略一的伪代码设计

    S={1};
    //还需对活动按照结束时间进行升序排序
    for (i=2;i<=n;i++){ if si>=fj{ append(S,i);//将该活动放到集合S中 j=i; } } return S;

    复杂度分析:O(nlogn)

    源代码:

    //
    //  main.cpp
    //  作业10
    //
    //  Created by yizhihenpidehou on 2020/4/28.
    //  Copyright © 2020 yizhihenpidehou. All rights reserved.
    //
    
    #include <iostream>
    #include <algorithm>
    #include <stdio.h>
    #include <string.h>
    using namespace std;
    struct A{
        int s;//开始时间
        int e;//结束时间
    }Act[200];
    bool cmp(struct A a,struct A b){
        return a.e<b.e;
    }
    void greedy(struct A* a,int n,int ap[]){
        sort(a+1,a+1+n,cmp);
        ap[1]=1;
        int j=1;//记录最新纳入计划的活动的序号
        int count=1;//记录有几个活动纳入计划
        for(int i=2;i<=n;i++){
            if(a[i].s>=a[j].e){//若当前活动与已纳入的最新活动兼容,则纳入计划
                ap[++count]=i;
                j=i;
            }
        }
        for(int i=1;i<=count;i++){
            printf("%d ",ap[i]);
        }
        printf("
    ");
    }
    int main(int argc, const char * argv[]) {
        Act[1].s=1;Act[1].e=2;
        Act[2].s=2;Act[2].e=3;
        Act[3].s=2;Act[3].e=4;
        Act[4].s=4;Act[4].e=6;
        Act[5].s=8;Act[5].e=12;
        Act[6].s=6;Act[6].e=12;
        int ap[200]={0};
        greedy(Act,6,ap);
        return 0;
    }
    View Code

     

  • 相关阅读:
    HDU 5045 5047 5050 5053(上海网络赛E,F,I,L)
    Xcode 5、Xcode 6 免证书真机调试
    Ubuntu打开终端的方法三种
    JAVA异常处理机制
    Java多线程之~~~~synchronized 方法
    iphone开发技术要学习的内容
    表达式求值(数据结构书上栈的应用之中的一个)
    Java学习篇之---json-lib(Maven)
    Nginx 笔记与总结(16)nginx 负载均衡
    SPSS数据记录的选择(Select Cases)
  • 原文地址:https://www.cnblogs.com/pipihoudewo/p/12796954.html
Copyright © 2020-2023  润新知