16-贪心/贪婪 算法 greedy algorithm

参考:《算法导论》第16章

贪心算法:在对问题求解时,总是做出在当前看来是最好的选择。

贪心算法的基本思路:

    1.建立数学模型来描述问题。

    2.把求解的问题分成若干个子问题。

    3.对每一子问题求解,得到子问题的局部最优解。

    4.把子问题的解局部最优解合成原来解问题的一个解。

活动选择问题:贪心算法最经典的例子:给出n个任务和每个任务的开始和结束时间,找出可以完成的任务的最大数量,在同一时刻只能做一个任务。

先把活动按照结束时间的单调递增顺序排序,最早结束的活动总是最优解的一部分。

#include <iostream>  
using namespace std;  
  
void GreedyChoose(int len,int *s,int *f,bool *flag)  
{  
    flag[0] = true;  
    int j = 0;  
    for(int i=1;i<len;++i)  
    { 
        if(s[i] >= f[j])    //前一个活动的结束时间早于后一个活动的开始时间 
        {  
            flag[i] = true;  
            j = i;  
        }  
    } 
}
  
int main()  
{  
    int s[11] ={1,3,0,5,3,5,6,8,8,2,12};  //开始时间 
    int f[11] ={4,5,6,7,8,9,10,11,12,13,14};   //结束时间 
  
    bool mark[11] = {false};  //标记 
  
    GreedyChoose(11,s,f,mark);  //贪心算法 
    
    for(int i=0;i<11;i++)  //输出结果 
        if(mark[i])  
            cout<<i<<" ";  
    return 0;  
}  
  
  

线段覆盖:在一维空间中告诉你N条线段的起始座标与终止座标,要求求出这些线段一共覆盖了多大的长度。

#include <iostream>  
using namespace std;  
  
int main()  
{  
    int s[10] = {2,3,4,5,6,7,8,9,10,11};  
    int f[10] = {3,5,7,6,9,8,12,10,13,15};  
    int TotalLength = (3-2);                   
    for(int i=1,j=0; i<10 ; ++i)  
    {  
        if(s[i] >= f[j])  
        {  
            TotalLength += (f[i]-s[i]);  
            j = i;  
        }  
        else  
        {  
            if(f[i] <= f[j])  
                continue;  
            else  
            {  
                TotalLength += f[i] - f[j];  
                j = i;  
            }  
        }  
    }  
    cout<<TotalLength<<endl;  
    return 0;  
}  
  

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章