最近学习了贪心算法,贪心算法是求局部最优解然后达到全部最优;
比如背包问题,过河问题一个是以性价比为贪心策略一个是以两种方法求最优,所以贪心的核心理念就是贪心算法追求局部最优,拿到问题之后先分析我们需要达到什么目标,是否适合采用贪心算法,并且使得什么最优以及实现的方法。我们一定要多方面去思考以不同的角度去看,就可以较好的解决相关问题;
所以当我们要运用贪心算法的时候的要从这几个方面去做;
第一我们要先把求解的问题分成若干个小问题,做出每一个小问题的最优解,最后整合这些小问题,贪心算法并不能求出所有情况,极端情况下是无法正确求解的。
比如一个经典例题会场安排问题
描述
学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办。小刘的工作就是安排学校小礼堂的活动,每个时间最多安排一个活动。现在小刘有一些活动计划的时间表,他想尽可能的安排更多的活动,请问他该如何安排。
输入
第一行是一个整型数m(m<100)表示共有m组测试数据。
每组测试数据的第一行是一个整数n(1<n<10000)表示该测试数据共有n个活动。
随后的n行,每行有两个正整数Bi,Ei(0<=Bi,Ei<10000),分别表示第i个活动的起始与结束时间(Bi<=Ei)
输出
对于每一组输入,输出最多能够安排的活动数量。
每组的输出占一行
样例输入
2
2
1 10
10 11
3
1 10
10 11
11 20
样例输出
1
2
读完题后我们首先注意到这活动只能一次举行一个,切当一个活动结束后才能进行下一个活动我们可以按照结束时间比较,排完序以后我们可以从第二个开始比较,当后面的开始时间比前面的结束时间大于1就可以完美错开然后举行活动。
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct meet
{
int start;
int end;
}a[100010];
bool cmp(meet a,meet b) //按会议结束时间排列
{
return a.end<b.end;
}
int main()
{
int x;
scanf("%d",&x);
while(x--)
{
int i;
int n;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d %d",&a[i].start,&a[i].end);
a[0].start=-1;
a[0].end=-1;
sort(a+1,a+n+1,cmp); //排列
int sum=1;
int j=1;
for(i=2;i<=n;i++) //从第二个会场开始从与前一个会场比较
{
if(a[i].start>a[j].end) //如果相隔时间大于1(输入都为整数),则活动数+1
{
j=i;
sum++;
}
}
cout<<sum<<endl;
}
return 0;
}