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分数规划)的更多相关文章

  1. poj 3111 K Best (二分搜索之最大化平均值之01分数规划)

    Description Demy has n jewels. Each of her jewels has some value vi and weight wi. Since her husband ...

  2. POJ 2976 Dropping tests【二分 最大化平均值】

    题意:定义最大平均分为 (a1+a2+a3+---+an)/(b1+b2+---+bn),求任意去除k场考试的最大平均成绩 和挑战程序设计上面的最大化平均值的例子一样 判断是否存在x满足条件 (a1+ ...

  3. poj 2976 Dropping tests 二分搜索+精度处理

    Dropping tests Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8349   Accepted: 2919 De ...

  4. NYOJ 914 Yougth的最大化【二分/最大化平均值模板/01分数规划】

    914-Yougth的最大化 内存限制:64MB 时间限制:1000ms 特判: No 通过数:3 提交数:4 难度:4 题目描述: Yougth现在有n个物品的重量和价值分别是Wi和Vi,你能帮他从 ...

  5. 二分算法的应用——最大化平均值 POJ 2976 Dropping tests

    最大化平均值 有n个物品的重量和价值分别wi 和 vi.从中选出 k 个物品使得 单位重量 的价值最大. 限制条件: <= k <= n <= ^ <= w_i <= v ...

  6. POJ - 2976 Dropping tests && 0/1 分数规划

    POJ - 2976 Dropping tests 你有 \(n\) 次考试成绩, 定义考试平均成绩为 \[\frac{\sum_{i = 1}^{n} a_{i}}{\sum_{i = 1}^{n} ...

  7. POJ - 2976 Dropping tests(01分数规划---二分(最大化平均值))

    题意:有n组ai和bi,要求去掉k组,使下式值最大. 分析: 1.此题是典型的01分数规划. 01分数规划:给定两个数组,a[i]表示选取i的可以得到的价值,b[i]表示选取i的代价.x[i]=1代表 ...

  8. POJ 2976 Dropping tests 【01分数规划+二分】

    题目链接:http://poj.org/problem?id=2976 Dropping tests Time Limit: 1000MS   Memory Limit: 65536K Total S ...

  9. POJ 2976 Dropping tests(01分数规划入门)

    Dropping tests Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11367   Accepted: 3962 D ...

随机推荐

  1. Oracle Directory文件夹的知识

    在上一章介绍expdp/impdp时曾使用过DIRECTORY这个概念,以下再简单说明下DIRECTORY的点点滴滴. MOS上对DIRECTORY的解释(266875.1): (1).基于服务端 v ...

  2. 大数据笔记11:MapReduce的运行流程

    1.基本概念 (1)Job & Task (2)JobTracker (3)TaskTracker

  3. 大数据笔记10:大数据之Hadoop的MapReduce的原理

    1. MapReduce(并行处理的框架) 思想:分而治之,一个大任务分解成多个小的子任务(map),并行执行后,合并结果(Reduce) (1)大任务分解成多个小任务,这个过程就是map: (2)多 ...

  4. Tabs( 选项卡)

    一. 加载方式 //class 加载方式<div id="box" class="easyui-tabs" style="width:500px ...

  5. 用Ant实现Java项目的自动构建和部署(转)

    Ant是一个Apache基金会下的跨平台的构件工具,它可以实现项目的自动构建和部署等功能.在本文中,主要让读者熟悉怎样将Ant应用到Java项目中,让它简化构建和部署操作. 一.            ...

  6. Linux 系统库函数coreleft 与sbrk简介

    coreleft   函数名: coreleft 功 能: 返回未使用内存的大小 用 法: unsigned coreleft(void); 程序例: #include <stdio.h> ...

  7. SQL Server系统表讲解

    1. sysobjects http://www.cnblogs.com/atree/p/SQL-Server-sysobjects.html   2.syscomments http://www.c ...

  8. dbutils的使用Demo

    首先了解一下 Queryrunner.query    —————只可以执行select语句. Queryrunner.update  —————只可以接收update,delte,insert语句 ...

  9. 新版本的strcpy_s

    char a[32] = "1234"; char b[32] ="123"; strcpy_s(b,sizeof(b), a + 2);//可以用strlen ...

  10. 线段树hdu1754

    #include<iostream>#include<stdio.h>using namespace std;const int maxa=200005;int val[max ...