在题目之前要知道贪心算法的基本步骤与实现过程
(1)贪心法的基本思路:
——从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止。
该算法存在问题:
- 不能保证求得的最后解是最佳的;
- 不能用来求最大或最小解问题;
- 只能求满足某些约束条件的可行解的范围
(2)实现该算法的过程:
从问题的某一初始解出发;
while 能朝给定总目标前进一步 do
求出可行解的一个解元素;
由所有解元素组合成问题的一个可行解;
会场安排问题
一、问题描述
假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效地贪心算法进行安排(这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个顶点,不相容的活动间用直线连接。使相邻点有着不同颜色的最小着色数,相应于要找的最小会场数)
二、算法分析
第一种:简易解法:我们将给的开始时间和结束时间进行排序,混排,得到一个数组,然后对应这个数组生成一个B数组,里面存放的是各个时间分别是开始时间还是结束时间,然后再创建一个C数组来保存会场的个数,遇到B数组中s就count++,遇到B数组中f就count–,然后再在C数组中找出最大值就是会场的个数!
第二种:贪心算法:我们将开始的时间和结束的时间分别放进两个数组里面,开始的时间是非递减序列,开始数组与结束数组一一对应,创建一个空的数组来进行排的过程,数组初始化为0,用开始数组里的数据和a数组进行比较,如果开始的数组中的数字大于a数组中的数字则表示上个活动在这个场地已经结束可以继续将下一个活动放入,反之的话就是,在排这个活动的时候上一个还没有结束,只能放到下一个演出厅中了,即a数组加一个数,如此循环,知道把开始时间的数组遍历完成,看a数组的长度或者每当加入时num加一,最后统计num即为个数!
三、具体过程
(1)混排
1 12 23 25 27 28 35 36 50 80
s s f s s f f s f f
1 2 1 2 3 2 1 2 1 0
最大值为3
(2)
s 1 12 25 27 36
f 23 28 35 80 50
a 23 28
35 28 80
35 50 80
看a的个数,只需要三个会场!
四、核心函数
for(i=2;i<=n;i++){
for(j=1;j<=num;j++){
if(s[i]>=f[a[j]]){a[j]=i;break;}
}
五、测试数据与结果
测试数据:5
1 23
12 28
25 35
27 80
36 50
测试结果:
六、代码
#include"stdio.h"
int main(){
int n,i,j,k,num,flag;
scanf("%d",&n)
int s[n+1],f[n+1],a[n+1];
for(i=1;i<=n;i++){
scanf("%d%d",&s[i],&f[i]);
a[i]=0;
}
a[1]=f[1];
num=1;
for(i=2;i<=n;i++){
flag = 1;
for(j=1;j<=num;j++){
if(s[i]>=a[j]){
a[j]=f[i];
flag = 0;
break;
}
}
if(flag == 1){
a[++num] = f[i];
}
}
printf("%d\n", num);
for(k=1;k<=num;k++)
printf("%d ",a[k]);
printf("\n");
printf("==============");
printf("\n");
printf("%d\n",num);
return 0;
}