题目2:招聘

时间限制: 3000ms 内存限制: 256MB

描述

Alice新开了一家公司,它的下面有两个项目,分别需要N1和N2个人来完成。现在有N个人前来应聘,于是Alice通过面试来决定他们中的哪些人会被录用。

Alice在面试中,会仔细考察他们能如何为公司的项目带来收益。她给每个人打了两个分值Q1和Q2,表示他加入第一个和第二项目分别能带来的收益值。同时,她也会仔细考察他们每个人的缺点,并且给每人打了另两个分值C1和C2,表示他们进入每个项目可能带来的负面效应。Alice心目中的最优决策是,在决定好录用哪些人以及每个人在哪个项目下工作之后,他们为公司带来的收益总和,除以他们为项目带来的负面效应总和,这个比值要最大。你能帮他计算出在最优决策下,这个比值为多少吗?

前来应聘的人数总是大于等于两个项目需求人数的总和,因此Alice一定会恰好招N1+N2个人,分配给第一个项目N1个人,分配给第二个项目N2个人,没有人会同时属于两个项目。

输入

输入文件包含多组测试数据。

第一行,给出一个整数T,为数据组数。接下来依次给出每组测试数据。

每组数据第一行为三个用空格隔开的整数N,N1,N2,表示前来应聘的人数,以及两个项目分别需要的人数。

接下来N行,每行是用空格隔开的四个整数Q1,C1,Q2,C2,依次表示每个人在第一个项目下的价值和负面效应,以及第二个项目下的价值和负面效应。

输出

对于每组测试数据,输出一行"Case #X: Y",其中X表示测试数据编号,Y表示最优决策下招募的人的价值总和与负面效应总和的比值,与正确答案的绝对误差不应超过10-6。所有数据按读入顺序从1开始编号。

数据范围

T ≤ 100

1 ≤ Q1, Q2 ≤ 2000

1 ≤ C1, C2 ≤ 50

小数据:0 < N1 + N2 ≤ N ≤ 50,

大数据:0 < N1 + N2 ≤ N ≤ 500

样例输入

1

5 2 2

12 5 8 3

9 4 9 4

7 3 16 6

11 5 7 5

18 10 6 3

样例输出

Case #1: 2.444444

 

解题思路

这是一道典型的01分数规划问题,我们想要求这样一个函数的最大值 f(x)/g(x)(g(x)>0), 我们只需找到最小的r,使得存在x满足h(x)=f(x)-r*g(x)>=0,这个r即为解。而这个r可以通过二分来确定。我们现在只需在给定r的条件下,求解f(x)-r*g(x)的最大值即可。

在这道问题中,f(x)=sum(Q1[i])+sum(Q2[j]) (i in S1, j in S2),g(x)=sum(C1[i])+sum(C2[j]) (i in S1, j in S2), 我们需要确定出两个集合S1,S2,使得f(x)-r*g(x)最大,即h(x)=sum(Q1[i]-r*C1[i])+sum(Q2[j]-r*C2[j])(i in S1, j in S2)。这里我们只需用动态规划来求解。令f[i][j][k]表示,在前i个人之中,有j个人属于S1,有k个人属于S2,此时最大的h(x)函数值为多少,转移很好考虑,即下一个人分在哪个项目或者不招进来。这样便能找到最大的h(x)。

仅仅做到这里还是不够,考虑到数据范围,这种做法可能会超时。一种优化思路是,当S1集合的人定下来时时,S2集合中的人一定可以贪心地选择剩余人中Q2[j]-r*C2[j]值最大的前N2个人,由此我们修改这个算法,先将所有人按Q2[j]-r*C2[j]从大到小排序,然后令f[i][j]表示前i个人之中,有j个人属于S2,并且不属于S1的人自动选前N2个人属于S2,此时h(x)的最大值。转移方式类似。如此一来,时间复杂度会下降一个阶,可以解决这道题目。

代码参考排名第二的zzz:学习一下,不愧为微软。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <map>
#include <string>
#include <cstring>
#include <sstream>
#include <algorithm>using namespace std;const int MAXN = 505;int n, n1, n2;
int q1[MAXN], c1[MAXN], q2[MAXN], c2[MAXN];
pair<double, double> a[MAXN];
double f[MAXN][MAXN];
bool ok(double ans)
{for (int i = 1; i <= n; ++i) {a[i] = make_pair(q1[i] - ans * c1[i], q2[i] - ans * c2[i]);}sort(a + 1, a + n + 1);reverse(a + 1, a + n + 1);double res = 0;f[0][0] = 0;for (int i = 1; i <= n; ++i) {f[i][0] = f[i - 1][0] + (i <= n1) * a[i].first;for (int j = 1; j < i && j <= n2; ++j) {f[i][j] = max(f[i - 1][j] + (i - j <= n1) * a[i].first, f[i - 1][j - 1] + a[i].second);}if (i <= n2) f[i][i] = f[i - 1][i - 1] + a[i].second;}for (int i = n1 + n2; i <= n; ++i)res = max(res, f[i][n2]);return res > 0;
}
void work()
{scanf("%d%d%d", &n, &n1, &n2);for (int i = 1; i <= n; ++i) {scanf("%d%d%d%d", &q1[i], &c1[i], &q2[i], &c2[i]);}double f = 0, r = 20000;for (int tmp = 0; tmp < 70; ++tmp) {double mid = (f + r) / 2;if (ok(mid)) f = mid;else r = mid;}printf("%.6f\n", (f+r)/2);
}
int main()
{int cases;scanf("%d", &cases);for (int tcase = 1; tcase <= cases; ++tcase) {printf("Case #%d: ", tcase);work();}return 0;
}

2013编程之美挑战赛复赛第二轮---招聘相关推荐

  1. 2013 编程之美挑战赛 仙剑5前传之璇光殿

    时间限制: 4000ms 内存限制: 256MB 描述 仙剑是一款经典的RPG游戏,最近又推出了仙剑5前传.Alice身为忠实的仙剑粉丝,当然是在第一时间就开始玩了.迷宫以及各类小游戏是仙剑系列的一大 ...

  2. [微软编程之美挑战赛P2]女神---CLJ神犇的代码

    Time Limit:20000ms Case Time Limit:10000ms Memory Limit:256MB Description 在 牧场物语 游戏中,如果第一次进入游戏就是春1日, ...

  3. 2013年微软编程之美大赛初赛第二题(博客园居然可以插入代码!!)

    描述 对于两个长度相等的字符串,我们定义其距离为对应位置不同的字符数量,同时我们认为距离越近的字符串越相似.例如,"0123"和"0000"的距离为 3,&qu ...

  4. 石头剪刀布 -2013编程之美全国测试赛 每日一练

    Description:石头剪刀布是常见的猜拳游戏.石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一样,则不分胜负. 一天,小A和小B正好在玩石头剪刀布.已知他们的出拳都是有规律的,比如:" ...

  5. 2013编程之美资格赛【传话游戏】

    时间限制: 1000ms 内存限制: 256MB 描述 Alice和Bob还有其他几位好朋友在一起玩传话游戏.这个游戏是这样进行的:首先,所有游戏者按顺序站成一排,Alice站第一位,Bob站最后一位 ...

  6. 2014编程之美挑战赛初赛 (程式之美初賽第一場)

    website: http://hihocoder.com/contest/msbop2014r2a P1 : 焦距 Time Limit:2000ms Case Time Limit:1000ms ...

  7. 2014编程之美资格赛

    2014 编程之美挑战赛 --- 资格赛真题 题目1 : 同构 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定2个树A和B,保证A的节点个数>=B的节点个数. ...

  8. 转: 多益网络2013校园招聘第二轮笔试题目

    多益网络2013校园招聘第二轮笔试题目 转载于:https://www.cnblogs.com/kira2will/p/4039539.html

  9. 多益网络2013校园招聘第二轮笔试题目

    前几天去参加了多益的校园招聘,年薪10W的程序员待遇让一帮程序员屌丝感到甚是激动,第一轮笔试难度一般,看看网上的c.c++题目基本就差不多了,还有两个思维题目. 思维题目一:有20张上下表面光滑的扑克 ...

最新文章

  1. python语音播报-Python实现有道翻译+语音播报
  2. 百度数据可视化图表套件echart实战
  3. git常用命令流程图
  4. override render 方法
  5. javascript基础-ajax
  6. 云服务器的主要用途是什么?
  7. 阶段5 3.微服务项目【学成在线】_day01 搭建环境 CMS服务端开发_04-项目概述-技术栈和开发步骤...
  8. 现场看女排vs日本了
  9. UVA ~ 816 ~ Abbott's Revenge (BFS + 打印路径)
  10. MySQL的事务特性
  11. 关于Behavior的使用方法
  12. 研究人员发现英特尔芯片组中可能被黑客使用的“新功能”VISA
  13. Unity 反转法线,在 Hierarchy 视图对象的快捷菜单中增加 Flip Mesh Normals(反转网格法线)项...
  14. 树莓派开启SSH、VNC远程桌面、开启root账号以及换国内镜像源码等
  15. ArcEngine中的ICommand接口和ITool接口
  16. Base64的编码(Encode)与解码(Decode)
  17. 【Java基础】· IO流习题详解
  18. python中.mat的图像数据怎么转换为.npy的数据
  19. 网络学习(一)--基本模型学习
  20. python 召回率_使用sklearn获取精确性和召回率

热门文章

  1. 微信、QQ自动抢红包外挂(绿色、无广告--附源码)
  2. 日立HGP03调试软件日立HGP03调试软件
  3. 网络爬虫是怎么运行的
  4. Java备忘录《数据类型》
  5. 升级的脉脉,正在以招聘业务铺开商业化版图
  6. 人眼视觉介绍,像素,分辨率,帧率,码率,清晰度关系
  7. 颠覆传统网文?有人已经用ChatGPT写书,放网上卖了第一桶金!
  8. oracle知识点复习总结
  9. Mockplus走进西南科技大学
  10. 完全二叉树的权值-JavaA