-
问题
相容问题,解析时给出其他几种贪心策略(如按开始时间从小到大、每个活动时间的占用时间等),并给出这些贪心策略无法实现最优的反例。
问题描述
有n项活动申请使用同一个礼堂,每项活动有一个开始时间和一个截止时间。如果任何两个活动不能同时举行,问如何选择这些活动,从而使得被安排的活动数量达到最多。 -
解析
[问题的理解和推导,可用电子版直接在此编写,也可用纸笔推导,拍照嵌入本文档]
建模:设S={1,2,…,n}为活动的集合,si和fi分别为活动i的开始和截止时间,i=1,2,…,n
定义:活动i和j相容 si>=fi或sj>=fi,i≠j
求S最大的两两相容的活动子集A。
按开始时间从小到大:
-
设计
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct huodong{
int ss;
int ee;
int time;
}A[130];
void sort(huodong A[],int n) {
for (int i = 0; i < n - 1; i++)
{
for (int j = 1; j < n - i; j++)
{
if (A[j - 1].end > A[j].end)
{
int temp = A[j - 1].end;
A[j - 1].end = A[j].end;
A[j].end = temp;
temp = A[j - 1].start;
A[j - 1].start = A[j].start;
A[j].start = temp;
temp = A[j - 1].time;
A[j - 1].time = A[j].time;
A[j].time = temp;
}
}
}
}
int f(huodong A[],int n) {
int k = 1;
int lastend = A[0].end;
for (int i = 1; i < n; i++)
{
if (A[i].start > lastend)
{
k++;
lastend = A[i].end;
}
}
return k;
}
int main(){
int l,pp;
printf("请输入活动数目:");
scanf("%d", &l);
printf("请输入输入活动开始和结束时间:");
for(pp = 0; pp < l; pp++){
scanf("%d", &A[pp].ss);
scanf("%d", &A[pp].ee);
A[pp].time = A[pp].ee - A[pp].ss;
}
sort(A,l);
printf("%d", f(A, l));
}
- 分析
时间复杂度:T(n)=O(n)