题目链接:点击打开链接
题目大意:安排期末考试的科目,时间区间为[ s, t) ,左闭右开,没有时间重叠的课程不能安排在一起,让尽量多的课程安排在一起,最少能安排多少天
题目分析:贪心算法,关键看怎么贪心,求重叠部分最多的
0------------------4
1-----------------5
2-----------------6
3------------6
重叠为3,所以先对起始时间排序,然后从前到后找重叠区间,当遇到没重叠区间时,自动跳到下一天
题目总结:1. 程序差十万八千里,但是样例过了= =->很容易将变量i 和j 搞错了
2.注意因为排序所以一定要存储初始的顺序,而不是i或者j
3.我的代码还是这样粗糙,很多时候觉得算法没错往往wa,自己虽然知道一定是范二了但是还是没哟办法= =
给一些样例吧:
4
1 5
1 2
2 3
3 4
4
1 2
1 4
2 4
5
1 4
1 3
2 4
3 7
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
struct node
{
int s,t,day;
};
int n;
vector<int >q[100005];
node info[100005];
int cmp(node a,node b)
{
return (a.s<b.s);
}
int main()
{
freopen("in.txt","r",stdin);
int i,count,j;
int a ,b;
while(scanf("%d",&n)!= EOF)
{
for(i=1;i<=n;i++)
{scanf("%d %d",&info[i].s,&info[i].t);q[i].clear();
info[i].day=i;
}
sort(info+1,info+1+n,cmp);
j=1, count=1;
while(j<=n)
{
a=info[j].s, b=info[j].t;
q[count].push_back(info[j].day);
for(i=j+1;i<=n;i++)
{
if(info[i].s<b)
{
a=max(a,info[i].s);b=min(b,info[i].t);
if(a==b) break;
q[count].push_back(info[i].day);
}
else break;
}
j=i;
count++;
}
printf("%d\n",count-1);
for(i=1;i<count;i++)
{
printf("%d",q[i][0]);
for(j=1;j<q[i].size();j++)
printf(" %d",q[i][j]);
printf("\n");
}
printf("\n");
}
return 0;
}