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

题目链接:http://poj.org/problem?id=2976

Dropping tests

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 17838   Accepted: 6186

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

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).

Source

 

题目概述:

N个物品,每个物品 i 有 a[ i ] 和 b[ i ] 两种属性,去掉K个物品,是的 Σai / Σbi 最大。

解题思路:

我们令 Σai / Σbi >= x, 然后二分x,而判断条件则移一下项得 Σai >= Σbi*x  → Σai - Σbi*x >= 0,因为我们要去掉 K 个小的, 取N-K个使结果最大化的,所以用 令 p[ i ] =  Σai - Σbi*x,对 p[ i ] 默认升序排序之后,第 K 到 N 个。判断这些数和是否满足不等式条件(大于等于0)

注意事项:

因为计算机的精度问题,要注意细节的处理,对浮点数的计算。(in代码)

 

AC code:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #define INF 0x3f3f3f3f
 7 #define ll long long int
 8 using namespace std;
 9 
10 const int MAXN =  2048;
11 int N, K;
12 int a[MAXN], b[MAXN];
13 double p[MAXN];       ///这里的p一定要是浮点型,因为本来就是计算分式
14 
15 bool ok(double x)
16 {
17     for(int i = 1; i <= N; i++)
18     {
19         p[i] = a[i]-b[i]*x;
20     }
21     sort(p+1, p+N+1);
22     double ans = 0;
23     for(int j = N; j > K; j--)
24     {
25         ans+=p[j];
26     }
27     return ans>=0;
28 }
29 
30 int main()
31 {
32     while(~scanf("%d%d", &N, &K) && N|K)
33     {
34         for(int i = 1; i <= N; i++)
35         {
36             scanf("%d", &a[i]);
37         }
38         for(int i  = 1; i <= N; i++)
39         {
40             scanf("%d", &b[i]);
41         }
42         double l = 0, r = 1;
43         while(r-l>1e-6)        //!!!这里不用0,是因为计算机精度问题,计算浮点数要保留一定误差,改成0会超时
44         {
45             double mid = (l+r)/2.0;
46             if(ok(mid)) l = mid;
47             else r = mid;
48         }
49         printf("%.0lf\n", l*100);
50     }
51     return 0;
52 }
View Code

 

posted @ 2018-08-05 14:06  莜莫  阅读(138)  评论(0编辑  收藏  举报