http://acm.nyist.net/JudgeOnline/problem.php?pid=914
Maximum time limit for yougth: +Ms | Memory Limit:65535KB Difficulty:4
-
-
Describe
-
Yougth now has the weight and value of n items are WI and VI, can you help him to choose K items to make the value of the unit weight maximum?
-
-
Input
-
-
There are multiple sets of test data
The first row of each set of test data has two numbers n and K, and the next line has n number of WI and VI.
(1<=k=n<=10000) (1<=wi,vi<=1000000)
-
-
Output
-
-
the output gives the maximum value of the unit value. (two decimal places reserved)
-
-
Sample input
-
-
3 22 25) 32 1
-
-
Sample output
-
-
0.75
-
-
Source
-
-
Yougth
/* Binary search + greedy choice * Binary search: First of all, you need to know the unit value of K (any) item does not exceed the unit value of the largest individual item, you have to think about it * so ans (assuming the final answer) must be in 0-maximum single item unit value between, we can use the dichotomy To narrow the range until the accuracy is met. As to how to decide whether the interval range is to the left or to the right, it is necessary to judge the current answer and determine if there is a scheme to make the unit value of k items not lower than the current answer, and to judge the existence of the scheme needs greedy choice. * Greedy choice: (V1+V2+...+VK)/(W1+W2+...+WK) >=cur_ans (i.e. current answer) * Convert this formula to: (V1-CUR_ANS*W1) + (V2-CUR_ANS*W2) +. (VK-CUR_ANS*WK) >= 0 * At this point, we can see that we can do a non-incrementing array of VI-CUR_ANS*WI, select the first k as a scheme */#include <iostream>using name Space STD, #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include < Algorithm> #define EPS 1e-3 #define MAXN 10005 int n,k;double v[maxn],w[maxn];int Check (double x) {double A[MAXN]; for (int i = 0; i < n; ++i) {a[i] = V[i]-x*w[i]; } sort (a,a+n); Reverse (a,a+n); Double sum =. 0; for (int i = 0; i < K; ++i) {sum + = A[i]; } return (sum >=0)? 1:0;} Double Fenzhi (double right) {double L = 0, r = right; while (R-l > EPs) {double mid = (l+r)/2; if (check (mid)) {L = mid; } else {r = Mid; }} return L;} int main () {while (CIN >> n >> k) {Double right =-1; for (int i = 0; i < n; ++i) {cin >> w[i] >> v[i]; right = Max (Right,v[i]*1.0/w[i]); } printf ("%.2lf\n", Fenzhi (right)); } return 0; }
Maximizing the Nyoj yougth