poj 2976 Dropping tests (二分搜索之最大化平均值之01分数规划)
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 tests with scores of /, /, and /. 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, ≤ n ≤ and ≤ k < n. The second line contains nintegers indicating ai for all i. The third line contains n positive integers indicating bi for all i. It is guaranteed that ≤ ai ≤ bi ≤ , , , . The end-of-file is marked by a test case with n = k = 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).
Source
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
#include<stdlib.h>
using namespace std;
#define N 1006
int n,k;
double ratio;
struct Node{
double a,b;
bool friend operator <(Node x,Node y){
return x.a-ratio*x.b>y.a-ratio*y.b;
}
}node[N];
bool solve(double mid){
ratio=mid;
sort(node,node+n);
double sum1=;
double sum2=;
for(int i=;i<n-k;i++){
sum1+=node[i].a;
sum2+=node[i].b;
}
return sum1/sum2>=mid;
} int main()
{
while(scanf("%d%d",&n,&k)== && n+k!=){
for(int i=;i<n;i++){
scanf("%lf",&node[i].a);
}
for(int i=;i<n;i++){
scanf("%lf",&node[i].b);
}
double low=;
double high=;
for(int i=;i<;i++){
double mid=(low+high)/;
if(solve(mid)){
low=mid;
}
else{
high=mid;
}
}
printf("%.0lf\n",high*);
}
return ;
}
乍看以为贪心或dp能解决,后来发现贪心策略与当前的总体准确率有关,行不通,于是二分解决。
依然需要确定一个贪心策略,每次贪心地去掉那些对正确率贡献小的考试。如何确定某个考试[a_i, b_i]对总体准确率x的贡献呢?a_i / b_i肯定是不行的,不然例子里的[0,1]会首当其冲被刷掉。在当前准确率为x的情况下,这场考试“额外”对的题目数量是a_i – x * b_i,当然这个值有正有负,恰好可以作为“贡献度”的测量。于是利用这个给考试排个降序,后k个刷掉就行了。
之后就是二分搜索了,从0到1之间搜一遍,我下面的注释应该很详细,不啰嗦了。
#ifndef ONLINE_JUDGE
#pragma warning(disable : 4996)
#endif
#include <iostream>
#include <algorithm>
#include <cmath>
#include <iomanip>
using namespace std; #define MAX_N 1000
int n, k;
double x; // 搜索过程中的正确率
struct Test
{
int a, b;
bool operator < (const Test& other) const
{
return a - x * b > other.a - x * other.b; // 按照对准确率的贡献从大到小排序
}
};
Test test[MAX_N]; // 判断是否能够获得大于mid的准确率
bool C(double mid)
{
x = mid;
sort(test, test + n);
double total_a = , total_b = ;
for (int i = ; i < n - k; ++i) // 去掉后k个数计算准确率
{
total_a += test[i].a;
total_b += test[i].b;
} return total_a / total_b > mid;
} ///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
while (cin >> n >> k && (n || k))
{
for (int i = ; i < n; ++i)
{
cin >> test[i].a;
}
for (int i = ; i < n; ++i)
{
cin >> test[i].b;
} double lb = ; double ub = ;
while (abs(ub - lb) > 1e-)
{
double mid = (lb + ub) / ;
if (C(mid))
{
lb = mid; // 行,说明mid太小
}
else
{
ub = mid; // 不行,说明mid太大
}
} cout << fixed << setprecision() << lb * << endl;
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
system("out.txt");
#endif
return ;
}
///////////////////////////End Sub//////////////////////////////////
poj 2976 Dropping tests (二分搜索之最大化平均值之01分数规划)的更多相关文章
- poj 3111 K Best (二分搜索之最大化平均值之01分数规划)
Description Demy has n jewels. Each of her jewels has some value vi and weight wi. Since her husband ...
- POJ 2976 Dropping tests【二分 最大化平均值】
题意:定义最大平均分为 (a1+a2+a3+---+an)/(b1+b2+---+bn),求任意去除k场考试的最大平均成绩 和挑战程序设计上面的最大化平均值的例子一样 判断是否存在x满足条件 (a1+ ...
- poj 2976 Dropping tests 二分搜索+精度处理
Dropping tests Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8349 Accepted: 2919 De ...
- NYOJ 914 Yougth的最大化【二分/最大化平均值模板/01分数规划】
914-Yougth的最大化 内存限制:64MB 时间限制:1000ms 特判: No 通过数:3 提交数:4 难度:4 题目描述: Yougth现在有n个物品的重量和价值分别是Wi和Vi,你能帮他从 ...
- 二分算法的应用——最大化平均值 POJ 2976 Dropping tests
最大化平均值 有n个物品的重量和价值分别wi 和 vi.从中选出 k 个物品使得 单位重量 的价值最大. 限制条件: <= k <= n <= ^ <= w_i <= v ...
- POJ - 2976 Dropping tests && 0/1 分数规划
POJ - 2976 Dropping tests 你有 \(n\) 次考试成绩, 定义考试平均成绩为 \[\frac{\sum_{i = 1}^{n} a_{i}}{\sum_{i = 1}^{n} ...
- POJ - 2976 Dropping tests(01分数规划---二分(最大化平均值))
题意:有n组ai和bi,要求去掉k组,使下式值最大. 分析: 1.此题是典型的01分数规划. 01分数规划:给定两个数组,a[i]表示选取i的可以得到的价值,b[i]表示选取i的代价.x[i]=1代表 ...
- POJ 2976 Dropping tests 【01分数规划+二分】
题目链接:http://poj.org/problem?id=2976 Dropping tests Time Limit: 1000MS Memory Limit: 65536K Total S ...
- POJ 2976 Dropping tests(01分数规划入门)
Dropping tests Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11367 Accepted: 3962 D ...
随机推荐
- DevExpress之列表控件
listBoxControl和checkedListBoxControl 常用属性 DataSource---------数据源 DisplayMember-----默认显示成员 这两个属性是list ...
- 让 Dreamweaver 支持 Emmet(原ZenCoding)
注:目前暂不支持 DW CC,期待作者早是更新.Update:2013/10/12 鉴于某些原因,每个 Coder 所钟爱的 IDE 各不相同.而作为一个软件爱好者,我几乎所有 IDE 都使用过一段时 ...
- 程序猿的道路~~(How to be a programmer?)
程序猿的道路其实很简单,主要就是三条: Learn (学习), Practice(练习), Summary(总结) 推荐给新手程序猿两篇文章: 给程序员新手的一些建议 程序员技术练级攻略 当然了,整个 ...
- [RxJS] Creation operator: of()
RxJS is a lot about the so-called "operators". We will learn most of the important operato ...
- Nginx的安装及简单配置
Nginx安装 1.下载相关组件 yum install -y gcc gcc-c++ #安装C/C++编译器 yum -y ins ...
- C复习手记(Day1)
auto存储类:所有局部变量默认的存储类 ex:{int mount;auto int month} auto只用在函数内,只做局部变量 register 存储类:register 存储类用于定义 ...
- 获取GET/POST提交的数据,并处理中文问题
1.获取input标签中的值,用request.getParameter("User")(User为input的name值) 2. 获取checkbox的值,由于是多选的,所以不能 ...
- C#使用itextsharp生成PDF文件
项目需求需要生成一个PDF文档,使用的是VS2010,ASP.NET. 网络上多次搜索没有自己想要的,于是硬着头皮到itextpdf官网看英文文档,按时完成任务,以实用为主,共享一下: 使用HTML文 ...
- 3月23日html(四) 格式与布局
一.position:fixed 锁定位置(相对于浏览器的位置),例如有些网站的右下角的弹出窗口. 二.position:absolute 1.外层没有position:absolute(或relat ...
- google 地图,多个标记 js库
360 云盘:http://yunpan.cn/cVgU3X7JFxAGY (提取码:1f07) 百度云盘:链接: http://pan.baidu.com/s/1c0fbCWw 密码: w1pm 参 ...