題目:
有n個需要在同一天使用同一個教室的活動a1,a2,…,an,教室同一時刻只能由一個活動使用。
每個活動ai都有一個開始時間si和結束時間fi 。一旦被選擇後,活動ai就佔據半開時間區間[si,fi)。
如果[si,fi]和[sj,fj]互不重疊,ai和aj兩個活動就可以被安排在這一天。
該問題就是要安排這些活動使得儘量多的活動能不衝突的舉行。
例如下圖所示的活動集合S,其中各項活動按照結束時間單調遞增排序。
這道題用貪心策略來求解
1.首先將n個活動的開始時間與結束的時間都放在一個結構體中,並且爲這個結構體根據每個活動的結束時間進行升序排序
2.此時第一個最早結束的爲第一個活動,之後第二個活動開始進行遍歷用其開始時間與之前的結束時間進行比較,若是大於等於之前的結束時間,那麼就會將這個活動計算在內,此時下一個比較的就是這個新的活動的結束時間
3.最後得出有限時間內最多參加活動的數量
簡而言之就是根據結束時間排序,然後從第二個開始不斷與最近活動的結束時間進行比較,若是符合就加入活動數中
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int n; //輸入活動的總數
struct Act{
int start;
int end;
}act[10000];
bool cmp(Act x,Act y){
return x.end<y.end;
}
//求出對應時間內可以做的最多事情
int greed_activity(){
int num=1,i=1;0
//默認從第二件開始,之前已經按照最早的結束時間排序過了
for(int j=2;j<=n;j++){
if(act[j].start>=act[i].end){
i=j;
num++;
}
}
return num;
}
void print(Act x)
{
cout<<"stat:"<<x.start<<" end:"<<x.end<<endl;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&act[i].start,&act[i].end);
}
act[0].start=-1;
act[0].end = -1;
sort(act+1,act+n+1,cmp); //按照活動的最晚結束時間進行排序
//for_each(act+1,act+n+1,print); 遍歷算法調用庫中進行檢驗
int num = greed_activity();
cout<<num;
return 0;
}