• 贪心算法之区间调度问题


    问题主题:区间调度问题
    问题描述:
    有n项工作,每项工作分别在si开始,ti结束。对每项工作,你都可以选择参加或不参加,但选择了参加某项工作就必须至始至终参加全程参与,即参与工作的时间段不能有重叠(即使开始的时间和结束的时间重叠都不行)。
    限制条件:
    1<=n<=100000
    1<=si<=ti,=109
    样例:
    输入
    n=5
    s={1,2,4,6,8}
    T={3,5,7,9,10}
    输出

    3(选择工作1, 3, 5)

    对这个问题,如果使用贪心算法的话,可能有以下几种考虑:

    (1)、每次选取开始时间最早的;

    (2)、每次选取结束时间最早的;

    (3)、每次选取用时最短的;

    (4)、在可选工作中,每次选取与最小可选工作有重叠的部分;

    对于上面的四种算法,只有算法(2)是正确的,其它的三种都可以找到相应的反例。具体证明如下:

     

    数轴上有n个区间,选出最多的区间,使得这些区间不互相重叠。

    算法:

    将所有区间按右端点坐标从小到大排序,顺序处理每个区间。如果它与当前已选的所有区间都没有重叠,则选择该区间,否则不选。

    代码如下:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int MAXN=100000;
    pair<int,int> itv[MAXN];
    int main()
    {
        int i,j,n,s[MAXN],t[MAXN],tt=0,ans=0;//tt是所选工作的结束时间
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
            scanf("%d",&s[i]);
        }
        for(j=0;j<n;j++)
        {
            scanf("%d",&t[j]);
        }
        sort(itv,itv+n);
        for(i=0;i<=n;i++)//为了让结束时间早的工作排在前面,把t存在first,s存在second
        {
            itv[i].first=t[i];
            itv[i].second=s[i];
        }
        for(i=0;i<n;i++)
        {
            if(tt<itv[i].second)
            {
                ans++;
                tt=itv[i].first;
            }
        }
        cout<<ans<<endl;
        return 0;
    
    }
    


  • 相关阅读:
    MongoDB性能分析
    MongoDB复制
    redis键管理
    MySQL集群架构-DRBD+headbeat +lvs+keepalived
    Spark-Core RDD转换算子-双Value型交互
    Spark-Core RDD转换算子-Value型
    Spark-Core RDD的创建
    Spark-Core RDD概述
    数仓理论
    flume 进阶
  • 原文地址:https://www.cnblogs.com/Zeroinger/p/5493940.html
Copyright © 2020-2023  润新知