根据期末老师划的重点复习…=_=!
(1) 基本概念
- 贪心算法总是做出在当前看来是最好的选择
- 贪心算法不从整体最优上考虑,而是某种意义上的局部最优的选择
(2)基本要素
- 最优子结构性质:当一个问题的最优解包含其子问题的最优解时称为此问题具有最优子结构
- 贪心选择性质:所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到
(3)算法方式
自顶向下
(4)活动安排问题
- 问题描述
有n个活动集合,E(1,2,3…n),每个活动都使用同一个资源,第i个活动开始时间si一定要比在i前的活动的结束时间大,问怎么安排,使活动最多。 - 算法思想
贪心选择思想
j 存的是当前局部最优解的最后结束的活动
i 存的是当前局部最优解时,后面还没被安排在最优解的活动 - 算法步骤
①选择第一个活动为j(因为它是最早完成的,所以它一定包含在贪心选择中的局部最优解中)
②找第i个活动看是否大于j的结束时间f[j] 若大于,将选择第i个活动进入局部最优解中,A[i] 设为true是标记是否被选择。
③找到了第 i 个元素,更新此时的 j 的值为当前的 i 的值 - 核心算法实现
//核心算法
void GreedySelector(int n,int s[],int f[],bool A[]){
A[0] = true;
int j=0;
//用j表示结束时间f[j],i表示开始时间,s[i]
for(int i=1;i<n;i++){
//从i=1的开始和j=0的结束开始比较
if(s[i]>=f[j]){
A[i] = true;
//此时的j就等于i
j=i;
}
else A[i] = false;
}
}
- 完整算法实现
#include<stdio.h>
void GreedySelector(int n,int s[],int f[],bool A[]);
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 A[11];
int n=11;
int c=0;
GreedySelector(n,s,f,A);
for(int i=0;i<11;i++) if(A[i]) c++;
printf("一共有多少个活动%d",c);
}
void GreedySelector