活动选择问题,每个活动有一个开始时间和结束时间,希望选出一个最大的活动兼容集。
方法一,以结束之间为关键字,按非递减顺序排列所有活动,选择结束时间最早的活动,逐步递归即可得出一个最优解,最优解可能有多个。
方法二,以开始时间为关键字,按非递减顺序排列所有活动,选择开始时间最迟的活动,逐步递归即可得出一个最优解,最优解可能有多个。
1.递归算法
//贪心法求解活动选择问题
//自顶向下递归贪心算法
#include <iostream>
#include <cstring>
#define N 100
using namespace std;
struct time
{
int start;
int end;
};
int c[N];
int temp=1;
SELECT(time A[],int k,int n)
{
int m=k+1;
while(m<=n && A[k].end>A[m].start) m++;
if(m <= n)
{
c[temp]=m; temp++;
SELECT(A,m,n);
}
}
int main(int argc, char *argv[])
{
time A[N];
int n; cin >> n;
for(int i=1;i<=n;i++)
{
cin >> A[i].start >> A[i].end;
}
A[0].start=0; A[0].end=0;
memset(c,0,sizeof(c));
SELECT(A,0,n);
for(int i=1;i<temp;i++)
{
cout << c[i] << ends;
}
cout << endl;
cout << "Hello World!" << endl;
return 0;
}
2.迭代算法
//贪心法求解活动选择问题
//自顶向下迭代贪心算法
#include <iostream>
#include <cstring>
#define N 100
using namespace std;
struct time
{
int start;
int end;
};
SELECT(time A[],int k,int n)
{
int c[N];
memset(c,0,sizeof(c)); c[1]=k;
int temp=2;
for(int i=2;i<=n;i++)
{
if(A[k].end < A[i].start)
{
c[temp]=i; temp++;
k=i;
}
}
for(int i=1;i<temp;i++) cout << c[i] <<ends;
cout << endl;
}
int main(int argc, char *argv[])
{
time A[N];
int n; cin >> n;
for(int i=1;i<=n;i++) cin >> A[i].start >> A[i].end;
SELECT(A,1,n);
cout << "Hello World!" << endl;
return 0;
}