Swan学院社团招新(贪心算法求最大兼容子序列)
7-4 Swan学院社团招新 (20分)
Swan学院社团招新,招新宣讲会分散在不同时间段,大一新生小花花想知道自己最多能完整的参加多少个招新宣讲会(参加一个招新宣讲会的时候不能中断或离开)。 【问题说明】这个问题是对几个相互竞争的招新宣讲会活动进行调度,它们都要求以独占的方式使用某一公共资源(小花花)。调度的目标是找出一个最大的相互兼容的活动集合。 活动选择问题就是要选择出一个由互相兼容的问题组成的最大子集合。 【温馨提示】应先将所有的活动按照结束时间升序排列,然后再选择可能的时间组合,并求出最大的组合数,使用qsort()排序函数是一个不错的选择。
qsort 的函数原型是: void qsort(voidbase,size_t num,size_t width,int(__cdeclcompare)(const void,const void));
功 能: 使用快速排序例程进行排序 头文件:stdlib.h
参数:
1 待排序数组首地址;
2 数组中待排序元素数量;
3 各元素的占用空间大小;
4 指向函数的指针,用于确定排序的顺序
输入格式:
第一行为n,表示有n个招新宣讲会,接下来n行每行两个整数表示开始时间和结束时间,由从招新会第一天0点开始的小时数表示(24小时制)。 n <= 1000 。
输出格式:
最多参加的招聘会个数。
输入样例:
在这里给出一组输入。例如:
3
9 10
10 20
8 15
输出样例:
在这里给出相应的输出。例如:
2
实验代码(自己写的感觉有点菜)
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int start;
int end;
};
int Comp(const void* p1, const void* p2)
{
struct Node* a = (Node*)p1;
struct Node* b = (Node*)p2;
if (a->end != b->end)
return a->end - b->end;
else
return b->start - a->start;
}
int main()
{
struct Node num[1000];
int n;
int time[24] = { 0 };
int count = 0;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d %d", &num[i].start, &num[i].end);
}
qsort(num, n, sizeof(num[0]),Comp);
for (int i = 0; i < n; i++)
{
int flag = 1;
for (int k = num[i].start; k < num[i].end; k++)
{
if (time[k] == 1)
{
flag = 0;
break;
}
}
if (flag == 1)
{
for (int k = num[i].start; k < num[i].end; k++)
{
time[k] = 1;
}
count++;
}
}
printf("%d", count);
return 0;
}
实验代码(大佬写的)
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX = 1005;
struct hh
{
int start;
int end;
}a[MAX];
bool cmp(hh a, hh b)
{
return a.start < b.start;
}
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i].start >> a[i].end;
}
sort(a, a + n, cmp);//按开始时间从小到大排列
int end = a[0].end;
int sum = 1;
for (int i = 1; i < n; i++) //算法核心内容
{
if (a[i].start >= end) // 两个时间段没有重叠
{
sum++;
end = a[i].end;//记录结束时间
}
else if (a[i].end < end) //两个时间段重叠,看哪一个早结束
{
end = a[i].end;//记录结束时间
}
}
cout << sum << endl;
return 0;
}