问题分析:
会议/课程/任务调度问题也是典型的贪心策略问题。比如说,会议安排没有的事能在有限的时间内召开更多的会议。(任何两个会议不能同时进行)
算法设计:
- 初始化:将n个会议的开始事件、结束时间存放在结构体数组中,如果需要知道选中了哪些会议,还需要在结构体中增加会议编号,然后按结束时间从小到大排序,结束时间相等时,按开始事件从大到小排序。
- 根据岩心策略就是选择一个具有最早结束时间的会议,用last记录刚选中的结束时间。
- 选择第一个会议之后,依次从剩下未安排的会议中选择,如果会议i开始事件大于等于最后一个选中的会议的结束时间last,那么会议i与选中的会议相容,可以安排,更新last为刚才选中的会议的结束时间。否则,放弃i,检查下一个可以安排的会议
源代码:
#include <iostream> #include <algorithm> #include <cstdlib> #include <cstdio> #include <cstring> using namespace std; struct Meeting { int begin;//记录开始的时间 int end;//记录结束的时间 int number;//记录会议的编号 }meet[11111]; bool cmp(Meeting x,Meeting y) //排序,先结束的会议排前。 { if(x.end==y.end) { return x.begin>y.begin; } else { return x.end<y.end; } } class setMeet { public : int init(); int solve(); private: int n;//会议总数 int ans ;//最大会议安排总数 }; int setMeet::init() { int b,e;//表示会议开始和结束的时间 cout << "请输入会议总数:"<< endl; cin >> n; cout << "请输入会议开始和结束的时间,用空格分开" << endl; for (int i=0;i<n;i++) { cin >> b>>e; meet[i].begin=b; meet[i].end=e; meet[i].number=i+1; } } int setMeet :: solve () { sort(meet,meet+n,cmp); cout << " 排完序之后的会议时间如下:"<< endl; cout << "会议编号 " <<"开始事件 "<<"结束时间 "<<endl; int i; for (i=0;i<n;i++) { cout << " "<< meet[i].number <<"\t\t"<< meet[i].begin << "\t"<< meet[i].end<<endl; } cout << "--------------------------------------------------------------------------"<< endl; cout << "选择会议的过程"<< endl; cout << "选择第"<< meet[0].number<< "个会议"<< endl; ans=1; int last=meet[0].end;//设为第一个会议的结束时间。 for (i=1;i<n;++i) { if(meet[i].begin>=last)//如果下一个会议的开始事件比上一个会议的结束时间要晚 { ans++; last=meet[i].end; //更新last的值 cout<< "选择第"<< meet[i].number<< "个会议"<< endl; } } cout <<"可以安排" << ans << "个会议"<< endl; } int main() { setMeet sm; sm.init(); sm.solve(); return 0; }