POJ 2976 参数搜索

来源:互联网 发布:java用类定义数组 编辑:程序博客网 时间:2024/05/19 22:26
Dropping tests
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 3042 Accepted: 964

Description

In a certain course, you take n tests. If you get ai out ofbi 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 anyk 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 indicatingai for all i. The third line contains n positive integers indicatingbi for all i. It is guaranteed that 0 ≤ aibi ≤ 1, 000, 000, 000. The end-of-file is marked by a test case withn = k = 0 and should not be processed.

Output

For each test case, write a single line with the highest cumulative average possible after droppingk of the given test scores. The average should be rounded to the nearest integer.

Sample Input

3 15 0 25 1 64 21 2 7 95 6 7 90 0

Sample Output

83100

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

Stanford Local 2005

 

题意很明了,给你一个n一个k

然后输入两排数,假设分别是a1,a2,a3......an以及b1,b2,b3.....bn

那么假设r=sigma(ai)/sigma(bi)现在我们可以扔掉k对(ai,bi),让r的值最大

比如当输入是

3 1
5 0 2
5 1 6
时我们可以扔掉(2,,6)

从而使r=(5+0)/(5+1)=83.33333%

四舍五入取整得到83

 

思路:

我们可以首先假设那个最大的r为一个定值

那么得到以下等式:100*sigma(a[i])/sigma(b[i])=r

变化一下:100*sigma(a[i])-r*sigma(b[i])=0

------------------->sigma(100*a[i]-r*b[i])=0

非常典型的单调函数!!!可以利用二分查找进行求解(很像是01划分树的问题)

可以先用100*a[i]-r*b[i]进行排序,然后选前面的n-k个数,然后再去求和,如果sum>0则l=mid

反之则r=mid(循环的次数也必须>=15,我先开始写的10,由于精度不够高所以wa了一次)

 

我的代码:

#include<stdio.h>#include<algorithm>using namespace std;struct node{double a;double b;double x;};node in[1005];bool cmp(node p,node t){return p.x>t.x;}int main(){int n,k,i;double l,r,sum,mid;int time;while(scanf("%d%d",&n,&k)!=EOF){if(n==0&&k==0)break;time=15;for(i=0;i<n;i++)scanf("%lf",&in[i].a);for(i=0;i<n;i++)scanf("%lf",&in[i].b);l=0;r=100;while(time--){sum=0;mid=(l+r)/2;for(i=0;i<n;i++)in[i].x=100*in[i].a-mid*in[i].b;sort(in,in+n,cmp);for(i=0;i<n-k;i++)sum=sum+(100*in[i].a-mid*in[i].b);if(sum>0)l=mid;elser=mid;}printf("%.0lf/n",mid);}return 0;}


 

没有天分,只有勤奋!!

原创粉丝点击