贪心算法-活动安排问题

faiculty 2020-02-24

活动安排问题

  • 问题描述

    有n个需要使用同一资源的活动,且在同一时段只有一个活动能使用该资源。
    每个活动i都有一个起始时间 si 和结束时间 fi ,且 si < ei 。如果选择了活动 i,则它在半开时间区间 [si,ei) 内占用资源。若区间 [si, ei) 与区间 [sj,ej) 不相交,则称活动 i 与活动 j 是相容的。
    该问题就是要安排这些活动使得尽量多的活动能不冲突地举行。
    归纳: 活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合。

  • 解题思路

    每次总是选择具有最早完成时间的活动,为未安排活动留下尽可能多的时间。该算法的贪心选择的意义是使剩余的可安排时间段极大化,以便安排尽可能多的相容活动。
    贪心算法 是指在对问题求解时,不从整体最优上加以考虑,总是做出某种意义上的局部最优解。)

  • 解题步骤

    1.将各项活动按照结束时间单调递增排序;
    2.每次选择具有最早完成时间的活动,并计数。

  • 实例

兼容问题

设有 n 个任务,其中每个任务有一个起始时间 si 和一个结束时间 ei ,且 si < ei ,同一时间只能完成一个任务。如果选择了任务 i ,则它在时间区间 [si ,ei) 内占用资源。若区间 [si,ei) 与区间 [sj, ej)不相交,则称任务 i 与任务 j 是相容的。
那么,对于给定的任务时间区间,能互相兼容的最大任务个数是多少呢?

输入格式:

第一行一个整数 n (1<=n<=1000);
接下来 n 行,每行两个整数 si 和 ei 。

输出格式:

互相兼容的最大任务个数。

输入:

4
1 3
4 6
2 5
1 7

输出:

2

  • 完整代码
#include<stdio.h>

int main(){
   int n,i,j,number=1,t,final;
   int s[1200],e[1200];
   scanf("%d",&n);
   for(i=0;i<n;i++){
       scanf("%d%d",&s[i],&e[i]);
   }
   for(i=0;i<n-1;i++){
       for(j=0;j<n-i-1;j++){
           if(e[j]>e[j+1]){
               t=s[j];
               s[j]=s[j+1];
               s[j+1]=t;
               t=e[j];
               e[j]=e[j+1];
               e[j+1]=t;
           }
       }
   }
   final=e[0];
   for(i=1;i<n;i++){
       if(s[i]>=final){
           number++;
           final=e[i];
       }
   }
   printf("%d",number);
   return 0;
}

参考资料:从零开始学贪心算法

相关推荐