poj 2976 Dropping tests 【0-1分数规划】
2015-09-01 12:06
369 查看
Dropping tests
Description
In a certain course, you take n tests. If you get ai out of bi questions correct on test i, your cumulative average is defined to be
.
Given your test scores and a positive integer k, determine how high you can make your cumulative average if you are allowed to drop any k of your test scores.
Suppose you take 3 tests with scores of 5/5, 0/1, and 2/6. Without dropping any tests, your cumulative average is
. However, if you drop the third test, your cumulative average becomes
.
Input
The input test file will contain multiple test cases, each containing exactly three lines. The first line contains two integers, 1 ≤ n ≤ 1000 and 0 ≤ k < n. The second line contains n integers indicating ai for
all i. The third line contains n positive integers indicating bi for all i. It is guaranteed that 0 ≤ ai ≤ bi ≤ 1, 000, 000, 000. The end-of-file is marked by a test case
with n = k = 0 and should not be processed.
Output
For each test case, write a single line with the highest cumulative average possible after dropping k of the given test scores. The average should be rounded to the nearest integer.
Sample Input
Sample Output
Hint
To avoid ambiguities due to rounding errors, the judge tests have been constructed so that all answers are at least 0.001 away from a decision boundary (i.e., you can assume that the average is never 83.4997).
题意:给你N个二元组(a[i], b[i]),你可以从里面任意去掉K个。问你100 * sigma(a[i]) / sigma(b[i])的最大值。
以前做过一道类似的题目 ,看了别人题解AC之后就放那里了。现在看最小割,也用到分数规划,没办法只好看了。
分析:我们假设存在一种方案使得 o = sigma(a[i]) / sigma(b[i]) 的值 是最大的,我们可以转化这个式子并新设一个函数——sigma(t[i]) = sigma(a[i]) - sigma(b[i]) * o 。
切记,我们假设最大的o = sigma(a[i]) / sigma(b[i])才新设函数t[i]的。
这样的话,当o取最大值时,会满足sigma(t[i]) = 0。
反过来说sigma(t[i]) > 0时,说明当前的o不是最大的,还可以继续增大。
sigma(t[i]) < 0 时,说明当前的o过大,是不能满足的。
思路:二分枚举o的值,用当前的o值求出所有的t[i],累加最大的N-K个,判断这N-K个t[i]的值是否大于0。若大于0继续增大o值,小于o则减小o值。
AC代码:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 7828 | Accepted: 2739 |
In a certain course, you take n tests. If you get ai out of bi questions correct on test i, your cumulative average is defined to be
.
Given your test scores and a positive integer k, determine how high you can make your cumulative average if you are allowed to drop any k of your test scores.
Suppose you take 3 tests with scores of 5/5, 0/1, and 2/6. Without dropping any tests, your cumulative average is
. However, if you drop the third test, your cumulative average becomes
.
Input
The input test file will contain multiple test cases, each containing exactly three lines. The first line contains two integers, 1 ≤ n ≤ 1000 and 0 ≤ k < n. The second line contains n integers indicating ai for
all i. The third line contains n positive integers indicating bi for all i. It is guaranteed that 0 ≤ ai ≤ bi ≤ 1, 000, 000, 000. The end-of-file is marked by a test case
with n = k = 0 and should not be processed.
Output
For each test case, write a single line with the highest cumulative average possible after dropping k of the given test scores. The average should be rounded to the nearest integer.
Sample Input
3 1 5 0 2 5 1 6 4 2 1 2 7 9 5 6 7 9 0 0
Sample Output
83 100
Hint
To avoid ambiguities due to rounding errors, the judge tests have been constructed so that all answers are at least 0.001 away from a decision boundary (i.e., you can assume that the average is never 83.4997).
题意:给你N个二元组(a[i], b[i]),你可以从里面任意去掉K个。问你100 * sigma(a[i]) / sigma(b[i])的最大值。
以前做过一道类似的题目 ,看了别人题解AC之后就放那里了。现在看最小割,也用到分数规划,没办法只好看了。
分析:我们假设存在一种方案使得 o = sigma(a[i]) / sigma(b[i]) 的值 是最大的,我们可以转化这个式子并新设一个函数——sigma(t[i]) = sigma(a[i]) - sigma(b[i]) * o 。
切记,我们假设最大的o = sigma(a[i]) / sigma(b[i])才新设函数t[i]的。
这样的话,当o取最大值时,会满足sigma(t[i]) = 0。
反过来说sigma(t[i]) > 0时,说明当前的o不是最大的,还可以继续增大。
sigma(t[i]) < 0 时,说明当前的o过大,是不能满足的。
思路:二分枚举o的值,用当前的o值求出所有的t[i],累加最大的N-K个,判断这N-K个t[i]的值是否大于0。若大于0继续增大o值,小于o则减小o值。
AC代码:
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define eps 1e-8 #define MAXN 1010 using namespace std; int N, K; double a[MAXN], b[MAXN]; double t[MAXN]; bool judge(double o) { for(int i = 0; i < N; i++)//求t[i] t[i] = a[i] - o * b[i]; sort(t, t+N);//排序后 double sum = 0; for(int i = K; i < N; i++)//累加最大的N-K个 sum += t[i]; return sum >= 0; } int main() { while(scanf("%d%d", &N, &K), N||K) { for(int i = 0; i < N; i++) scanf("%lf", &a[i]); for(int i = 0; i < N; i++) scanf("%lf", &b[i]); double l = 0, r = 1; while(r - l >= eps) { double mid = (l + r) / 2; if(judge(mid)) l = mid; else r = mid; } printf("%.0lf\n", l * 100); } return 0; }
相关文章推荐
- CentOS安装配置VSFTP服务器
- 如何在Centos下设置Vim的永久显示行号功能?
- Friendly ARM开发板安装Linux系统教程
- 源码安装apache
- Dns+Nginx反向代理(超详细哦)~
- Hadoop短期学习笔记----阿冬专栏
- 相关网站地址
- SVN:This client is too old to work with working copy
- linux dd 创建ext3分区
- linux中查看进程执行情况
- Linux下调试PostgreSQL数据库
- 小议:如何监控SharePoint 2013 Web Page的Performance?
- 【转载】HBase基本概念和hbase shell常用命令用法
- linux跨主机复制文件
- 已解决:登录Linux的 -bash-4.2$ 问题
- 国人开发开源软件TOP100
- linux主机登录另一台linux主机
- MBR损坏修复(一)
- nginx+ajax跨域访问设置
- HDU 4364——Matrix operation——————【模拟题】