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;  
}  
  

 

 

 

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