• 贪心算法


    除了最优子结构性质之外,与动态规划不同的是,使用贪心算法解决的问题必须符合贪心选择性质

    通过作出局部最优(贪心)选择来构造全局最优解。

    在解决符合贪心选择性质的问题时,与动态规划算方法相比,贪心算法更简单、更高效。

    活动安排问题

    假定有一个n个活动的集合S={a1,a2,...,an},这些活动使用同一个资源(例如一个教室),而这个资源在某个时刻只能供一个活动使用。

    每个活动ai都有一个开始时间si和一个结束时间fi。我们希望选出一个最大兼容活动集(其中两两活动都不重叠)。例如,考虑下面的活动集合S:

    已按结束时间的单调递增顺序排序:

    我们可以使用贪心算法解决这个问题(可以有其他的贪心选择方案):

    每次我们从可以选择的活动集中选择最早结束的活动,并把它加入最优解。可以选择的活动集是S中开始时间大于fi(i是上次选择的活动)的活动。

    因为活动已按结束时间的单调递增顺序排序,因此第一次选择a1加入最优解。然后每次执行贪心选择,得到最优解。

    可以简单的证明一下:在满足相容条件下,使结束时间靠前的活动得到资源,这样为后续留下更多的时间,以使更多的活动得到安排。

    伪代码

    GREEDY-ACTIVITY-SELECTOR(s,f)
    n=s.length
    A={a1}
    k=1
    for m=2 to n
        if s[m]≥f[k]
            A=A∪{am}
            k=m
    return A

    其中A代表最大兼容的活动集,k记录了最近加入集合A的活动的下标。

    因为活动已按结束时间的单调递增顺序排序,所以只需要每次找出可以选择的活动集中的第一个活动加入A中。

    代码的实现与测试

     1 #define N 11
     2 #include <iostream>
     3 
     4 using namespace std;
     5 
     6 void greedy_activity_selector(int s[],int f[],int a[])
     7 {
     8     int i=0;
     9     a[i]=1;
    10     int k=1;
    11     for(int m=2;m<=N;++m)
    12     {
    13         if(s[m]>=f[k])
    14         {
    15             a[++i]=m;
    16             k=m;
    17         }
    18     }
    19 }
    20 
    21 
    22 int main()
    23 {
    24     int s[]={0,1,3,0,5,3,5,6,8,8,2,12};
    25     int f[]={0,4,5,6,7,9,9,10,11,12,14,16};
    26     int a[N]={0};
    27     greedy_activity_selector(s,f,a);
    28     int i=0;
    29     //输出最大兼容活动集的活动 
    30     while(a[i])
    31         cout<<a[i++]<<" ";
    32     cout<<endl;
    33     return 0;
    34 }
    View Code
  • 相关阅读:
    微信小程序-开发入门(一)
    Vue入门
    美化input type=range标签滑动样式(带渐变效果)
    全新的css网站布局--Grid布局
    移动端布局与样式上的坑
    swiper 下拉刷新混乱
    子元素scroll父元素容器不跟随滚动JS实现
    解决前端页面闪烁问题(转载)
    VUE 与其他常见前端框架对比
    移动端表层div滑动,导致底层body滑动(touchmove的阻止)
  • 原文地址:https://www.cnblogs.com/runnyu/p/4685885.html
Copyright © 2020-2023  润新知