您的位置:首页 > 编程语言

编程之美读书笔记之-高效率的安排见面会

2015-08-25 10:56 323 查看
问题一:

n个同学,分别对m个招聘见面会感兴趣。为了满足所有学生的要求,hr希望让每个同学都能参加自己所有感兴趣的见面会。然后每个见面会的时间为t。问如何安排见面会能够使得所有见面会总的时间最短。

建图,以m场见面会为节点,然后,对于每一个同学,如果它同时对A和B见面会感兴趣,那么,我们在A和B见面会之间添加一条边。要使得所有见面会总的时间最短,可以把所有的见面会分成若干的集合,规定,每个集合里面不能存这样两个见面会A和B,存在一个同学同时对A和B感兴趣。这样,一个集合的见面会是不是就可以同时进行了。

最后,我们发现,这不就是著名的NP问题之一的最少着色问题吗。还可以联想到并行处理器装载作业的问题啊,同时执行的任意两个作业不能需要同一个资源。这些类似的问题。不过,除了O((n-1)^n*n^2)的能够得到确定解的算法,据说还没有这个问题的有效算法,所以这里不予以讨论。

扩展问题一:

见面会之后,正式面试就陆续开始了。一共有N场面试,每场面试的时间是(B[i], E[i]),假设一个面试者一天只参加一场面试,为了使面试者能够发挥最佳状态,hr希望同时进行的面试可以安排在不同的地方。那么问题来了,最多需要多少个面试场所。

一组测试数据

A[1,5]

B[2,3]

C[3,4]

D[3,6]

如下图所示:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1e5 + 5;
struct node
{
int s,e;
}List[maxn];
int tree[maxn];

int lowbit(int x)
{
return x & (-x);
}
/*
单点插入操作
*/
void insert(int* A, int l, int d)
{
for(int i = l;i < maxn;i += lowbit(i))
A[i] += d;
}
/*
单点查询操作
*/
int query(int* A, int l)
{
int tot = 0;
for(int i = l;i >= 1;i -= lowbit(i))
tot += A[i];w
return tot;
}
int main()
{
//    freopen("in.txt", "r", stdin);
int n;  //n为区间个数
while(scanf("%d", &n)!=EOF)
{
int ans = 0;
memset(tree, 0, sizeof(tree));
int x, y, lmin = 0x7fffffff, lmax = 0;
for(int i = 0;i < n;i++)
{
scanf("%d%d", &x, &y);
lmin = min(lmin, x);   //获取所有区间的并集,减少不必要的遍历
lmax = max(lmax, y);
insert(tree, x, 1);
insert(tree, y, -1);
}
for(int i = lmin;i <= lmax;i++)
ans = max(ans, query(tree, i));
printf("%d\n", ans);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: