16-贪心/贪婪 算法 greedy algorithm

本文介绍贪心算法的基本思想,并通过两个实例进行说明:一是活动选择问题,通过将活动按结束时间排序并选取不冲突的活动以最大化参与数量;二是线段覆盖问题,计算给定线段集覆盖的一维空间总长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:《算法导论》第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;  
}  
  

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值